* Given two arrays of equal length and varying types, the standard * technique for sorting them in parallel is to create a new temporary * object for each row, store the objects in a temporary array, sort the * array using a custom comparator, and the extract the original values * back into their respective arrays. This is wasteful in both time and * memory. *
* This class generates bytecode customized to the particular set of * arrays you need to sort, in such a way that both arrays are sorted * in-place, simultaneously. *
* Two sorting algorithms are provided. * Quicksort is best when you only need to sort by a single column, as * it requires very few comparisons and swaps. Mergesort is best used * when sorting multiple columns, as it is a "stable" sort--that is, it * does not affect the relative order of equal objects from previous sorts. *
* The mergesort algorithm here is an "in-place" variant, which while
* slower, does not require a temporary array.
*
* @author Chris Nokleberg
*/
abstract public class ParallelSorter extends SorterTemplate {
protected Object[] a;
private Comparer comparer;
protected ParallelSorter() {
}
abstract public ParallelSorter newInstance(Object[] arrays);
/**
* Create a new ParallelSorter object for a set of arrays. You may
* sort the arrays multiple times via the same ParallelSorter object.
* @param arrays An array of arrays to sort. The arrays may be a mix
* of primitive and non-primitive types, but should all be the same
* length.
* @param loader ClassLoader for generated class, uses "current" if null
*/
public static ParallelSorter create(Object[] arrays) {
Generator gen = new Generator();
gen.setArrays(arrays);
return gen.create();
}
private int len() {
return ((Object[])a[0]).length;
}
/**
* Sort the arrays using the quicksort algorithm.
* @param index array (column) to sort by
*/
public void quickSort(int index) {
quickSort(index, 0, len(), null);
}
/**
* Sort the arrays using the quicksort algorithm.
* @param index array (column) to sort by
* @param lo starting array index (row), inclusive
* @param hi ending array index (row), exclusive
*/
public void quickSort(int index, int lo, int hi) {
quickSort(index, lo, hi, null);
}
/**
* Sort the arrays using the quicksort algorithm.
* @param index array (column) to sort by
* @param cmp Comparator to use if the specified column is non-primitive
*/
public void quickSort(int index, Comparator cmp) {
quickSort(index, 0, len(), cmp);
}
/**
* Sort the arrays using the quicksort algorithm.
* @param index array (column) to sort by
* @param lo starting array index (row), inclusive
* @param hi ending array index (row), exclusive
* @param cmp Comparator to use if the specified column is non-primitive
*/
public void quickSort(int index, int lo, int hi, Comparator cmp) {
chooseComparer(index, cmp);
super.quickSort(lo, hi - 1);
}
/**
* @param index array (column) to sort by
*/
public void mergeSort(int index) {
mergeSort(index, 0, len(), null);
}
/**
* Sort the arrays using an in-place merge sort.
* @param index array (column) to sort by
* @param lo starting array index (row), inclusive
* @param hi ending array index (row), exclusive
*/
public void mergeSort(int index, int lo, int hi) {
mergeSort(index, lo, hi, null);
}
/**
* Sort the arrays using an in-place merge sort.
* @param index array (column) to sort by
* @param lo starting array index (row), inclusive
* @param hi ending array index (row), exclusive
*/
public void mergeSort(int index, Comparator cmp) {
mergeSort(index, 0, len(), cmp);
}
/**
* Sort the arrays using an in-place merge sort.
* @param index array (column) to sort by
* @param lo starting array index (row), inclusive
* @param hi ending array index (row), exclusive
* @param cmp Comparator to use if the specified column is non-primitive
*/
public void mergeSort(int index, int lo, int hi, Comparator cmp) {
chooseComparer(index, cmp);
super.mergeSort(lo, hi - 1);
}
private void chooseComparer(int index, Comparator cmp) {
Object array = a[index];
Class type = array.getClass().getComponentType();
if (type.equals(Integer.TYPE)) {
comparer = new IntComparer((int[])array);
} else if (type.equals(Long.TYPE)) {
comparer = new LongComparer((long[])array);
} else if (type.equals(Double.TYPE)) {
comparer = new DoubleComparer((double[])array);
} else if (type.equals(Float.TYPE)) {
comparer = new FloatComparer((float[])array);
} else if (type.equals(Short.TYPE)) {
comparer = new ShortComparer((short[])array);
} else if (type.equals(Byte.TYPE)) {
comparer = new ByteComparer((byte[])array);
} else if (cmp != null) {
comparer = new ComparatorComparer((Object[])array, cmp);
} else {
comparer = new ObjectComparer((Object[])array);
}
}
protected int compare(int i, int j) {
return comparer.compare(i, j);
}
interface Comparer {
int compare(int i, int j);
}
static class ComparatorComparer implements Comparer {
private Object[] a;
private Comparator cmp;
public ComparatorComparer(Object[] a, Comparator cmp) {
this.a = a;
this.cmp = cmp;
}
public int compare(int i, int j) {
return cmp.compare(a[i], a[j]);
}
}
static class ObjectComparer implements Comparer {
private Object[] a;
public ObjectComparer(Object[] a) { this.a = a; }
public int compare(int i, int j) {
return ((Comparable)a[i]).compareTo(a[j]);
}
}
static class IntComparer implements Comparer {
private int[] a;
public IntComparer(int[] a) { this.a = a; }
public int compare(int i, int j) { return a[i] - a[j]; }
}
static class LongComparer implements Comparer {
private long[] a;
public LongComparer(long[] a) { this.a = a; }
public int compare(int i, int j) {
long vi = a[i];
long vj = a[j];
return (vi == vj) ? 0 : (vi > vj) ? 1 : -1;
}
}
static class FloatComparer implements Comparer {
private float[] a;
public FloatComparer(float[] a) { this.a = a; }
public int compare(int i, int j) {
float vi = a[i];
float vj = a[j];
return (vi == vj) ? 0 : (vi > vj) ? 1 : -1;
}
}
static class DoubleComparer implements Comparer {
private double[] a;
public DoubleComparer(double[] a) { this.a = a; }
public int compare(int i, int j) {
double vi = a[i];
double vj = a[j];
return (vi == vj) ? 0 : (vi > vj) ? 1 : -1;
}
}
static class ShortComparer implements Comparer {
private short[] a;
public ShortComparer(short[] a) { this.a = a; }
public int compare(int i, int j) { return a[i] - a[j]; }
}
static class ByteComparer implements Comparer {
private byte[] a;
public ByteComparer(byte[] a) { this.a = a; }
public int compare(int i, int j) { return a[i] - a[j]; }
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(ParallelSorter.class.getName());
private Object[] arrays;
public Generator() {
super(SOURCE);
}
protected ClassLoader getDefaultClassLoader() {
return null; // TODO
}
public void setArrays(Object[] arrays) {
this.arrays = arrays;
}
public ParallelSorter create() {
return (ParallelSorter)super.create(ClassesKey.create(arrays));
}
public void generateClass(ClassVisitor v) throws Exception {
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");
}
}
new ParallelSorterEmitter(v, getClassName(), arrays);
}
protected Object firstInstance(Class type) {
return ((ParallelSorter)ReflectUtils.newInstance(type)).newInstance(arrays);
}
protected Object nextInstance(Object instance) {
return ((ParallelSorter)instance).newInstance(arrays);
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/util/StringSwitcher.java 0000644 0001750 0001750 00000013534 10402432046 024013 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.util;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
/**
* This class implements a simple String->int mapping for a fixed set of keys.
*/
abstract public class StringSwitcher {
private static final Type STRING_SWITCHER =
TypeUtils.parseType("net.sf.cglib.util.StringSwitcher");
private static final Signature INT_VALUE =
TypeUtils.parseSignature("int intValue(String)");
private static final StringSwitcherKey KEY_FACTORY =
(StringSwitcherKey)KeyFactory.create(StringSwitcherKey.class);
interface StringSwitcherKey {
public Object newInstance(String[] strings, int[] ints, boolean fixedInput);
}
/**
* Helper method to create a StringSwitcher.
* For finer control over the generated instance, use a new instance of StringSwitcher.Generator
* instead of this static method.
* @param strings the array of String keys; must be the same length as the value array
* @param ints the array of integer results; must be the same length as the key array
* @param fixedInput if false, an unknown key will be returned from {@link #intValue} as -1
; if true,
* the result will be undefined, and the resulting code will be faster
*/
public static StringSwitcher create(String[] strings, int[] ints, boolean fixedInput) {
Generator gen = new Generator();
gen.setStrings(strings);
gen.setInts(ints);
gen.setFixedInput(fixedInput);
return gen.create();
}
protected StringSwitcher() {
}
/**
* Return the integer associated with the given key.
* @param s the key
* @return the associated integer value, or -1
if the key is unknown (unless
* fixedInput
was specified when this StringSwitcher
was created,
* in which case the return value for an unknown key is undefined)
*/
abstract public int intValue(String s);
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(StringSwitcher.class.getName());
private String[] strings;
private int[] ints;
private boolean fixedInput;
public Generator() {
super(SOURCE);
}
/**
* Set the array of recognized Strings.
* @param strings the array of String keys; must be the same length as the value array
* @see #setInts
*/
public void setStrings(String[] strings) {
this.strings = strings;
}
/**
* Set the array of integer results.
* @param ints the array of integer results; must be the same length as the key array
* @see #setStrings
*/
public void setInts(int[] ints) {
this.ints = ints;
}
/**
* Configure how unknown String keys will be handled.
* @param fixedInput if false, an unknown key will be returned from {@link #intValue} as -1
; if true,
* the result will be undefined, and the resulting code will be faster
*/
public void setFixedInput(boolean fixedInput) {
this.fixedInput = fixedInput;
}
protected ClassLoader getDefaultClassLoader() {
return getClass().getClassLoader();
}
/**
* Generate the StringSwitcher
.
*/
public StringSwitcher create() {
setNamePrefix(StringSwitcher.class.getName());
Object key = KEY_FACTORY.newInstance(strings, ints, fixedInput);
return (StringSwitcher)super.create(key);
}
public void generateClass(ClassVisitor v) throws Exception {
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
STRING_SWITCHER,
null,
Constants.SOURCE_FILE);
EmitUtils.null_constructor(ce);
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, INT_VALUE, null);
e.load_arg(0);
final List stringList = Arrays.asList(strings);
int style = fixedInput ? Constants.SWITCH_STYLE_HASHONLY : Constants.SWITCH_STYLE_HASH;
EmitUtils.string_switch(e, strings, style, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
e.push(ints[stringList.indexOf(key)]);
e.return_value();
}
public void processDefault() {
e.push(-1);
e.return_value();
}
});
e.end_method();
ce.end_class();
}
protected Object firstInstance(Class type) {
return (StringSwitcher)ReflectUtils.newInstance(type);
}
protected Object nextInstance(Object instance) {
return instance;
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/util/SorterTemplate.java 0000644 0001750 0001750 00000011723 10066633126 024014 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.util;
import java.util.*;
abstract class SorterTemplate {
private static final int MERGESORT_THRESHOLD = 12;
private static final int QUICKSORT_THRESHOLD = 7;
abstract protected void swap(int i, int j);
abstract protected int compare(int i, int j);
protected void quickSort(int lo, int hi) {
quickSortHelper(lo, hi);
insertionSort(lo, hi);
}
private void quickSortHelper(int lo, int hi) {
for (;;) {
int diff = hi - lo;
if (diff <= QUICKSORT_THRESHOLD) {
break;
}
int i = (hi + lo) / 2;
if (compare(lo, i) > 0) {
swap(lo, i);
}
if (compare(lo, hi) > 0) {
swap(lo, hi);
}
if (compare(i, hi) > 0) {
swap(i, hi);
}
int j = hi - 1;
swap(i, j);
i = lo;
int v = j;
for (;;) {
while (compare(++i, v) < 0) {
/* nothing */;
}
while (compare(--j, v) > 0) {
/* nothing */;
}
if (j < i) {
break;
}
swap(i, j);
}
swap(i, hi - 1);
if (j - lo <= hi - i + 1) {
quickSortHelper(lo, j);
lo = i + 1;
} else {
quickSortHelper(i + 1, hi);
hi = j;
}
}
}
private void insertionSort(int lo, int hi) {
for (int i = lo + 1 ; i <= hi; i++) {
for (int j = i; j > lo; j--) {
if (compare(j - 1, j) > 0) {
swap(j - 1, j);
} else {
break;
}
}
}
}
protected void mergeSort(int lo, int hi) {
int diff = hi - lo;
if (diff <= MERGESORT_THRESHOLD) {
insertionSort(lo, hi);
return;
}
int mid = lo + diff / 2;
mergeSort(lo, mid);
mergeSort(mid, hi);
merge(lo, mid, hi, mid - lo, hi - mid);
}
private void merge(int lo, int pivot, int hi, int len1, int len2) {
if (len1 == 0 || len2 == 0) {
return;
}
if (len1 + len2 == 2) {
if (compare(pivot, lo) < 0) {
swap(pivot, lo);
}
return;
}
int first_cut, second_cut;
int len11, len22;
if (len1 > len2) {
len11 = len1 / 2;
first_cut = lo + len11;
second_cut = lower(pivot, hi, first_cut);
len22 = second_cut - pivot;
} else {
len22 = len2 / 2;
second_cut = pivot + len22;
first_cut = upper(lo, pivot, second_cut);
len11 = first_cut - lo;
}
rotate(first_cut, pivot, second_cut);
int new_mid = first_cut + len22;
merge(lo, first_cut, new_mid, len11, len22);
merge(new_mid, second_cut, hi, len1 - len11, len2 - len22);
}
private void rotate(int lo, int mid, int hi) {
int lot = lo;
int hit = mid - 1;
while (lot < hit) {
swap(lot++, hit--);
}
lot = mid; hit = hi - 1;
while (lot < hit) {
swap(lot++, hit--);
}
lot = lo; hit = hi - 1;
while (lot < hit) {
swap(lot++, hit--);
}
}
private int lower(int lo, int hi, int val) {
int len = hi - lo;
while (len > 0) {
int half = len / 2;
int mid= lo + half;
if (compare(mid, val) < 0) {
lo = mid + 1;
len = len - half -1;
} else {
len = half;
}
}
return lo;
}
private int upper(int lo, int hi, int val) {
int len = hi - lo;
while (len > 0) {
int half = len / 2;
int mid = lo + half;
if (compare(val, mid) < 0) {
len = half;
} else {
lo = mid + 1;
len = len - half -1;
}
}
return lo;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/util/ParallelSorterEmitter.java 0000644 0001750 0001750 00000006752 10402432046 025325 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.util;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
class ParallelSorterEmitter extends ClassEmitter {
private static final Type PARALLEL_SORTER =
TypeUtils.parseType("net.sf.cglib.util.ParallelSorter");
private static final Signature CSTRUCT_OBJECT_ARRAY =
TypeUtils.parseConstructor("Object[]");
private static final Signature NEW_INSTANCE =
new Signature("newInstance", PARALLEL_SORTER, new Type[]{ Constants.TYPE_OBJECT_ARRAY });
private static final Signature SWAP =
TypeUtils.parseSignature("void swap(int, int)");
public ParallelSorterEmitter(ClassVisitor v, String className, Object[] arrays) {
super(v);
begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, PARALLEL_SORTER, null, Constants.SOURCE_FILE);
EmitUtils.null_constructor(this);
EmitUtils.factory_method(this, NEW_INSTANCE);
generateConstructor(arrays);
generateSwap(arrays);
end_class();
}
private String getFieldName(int index) {
return "FIELD_" + index;
}
private void generateConstructor(Object[] arrays) {
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null);
e.load_this();
e.super_invoke_constructor();
e.load_this();
e.load_arg(0);
e.super_putfield("a", Constants.TYPE_OBJECT_ARRAY);
for (int i = 0; i < arrays.length; i++) {
Type type = Type.getType(arrays[i].getClass());
declare_field(Constants.ACC_PRIVATE, getFieldName(i), type, null);
e.load_this();
e.load_arg(0);
e.push(i);
e.aaload();
e.checkcast(type);
e.putfield(getFieldName(i));
}
e.return_value();
e.end_method();
}
private void generateSwap(final Object[] arrays) {
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SWAP, null);
for (int i = 0; i < arrays.length; i++) {
Type type = Type.getType(arrays[i].getClass());
Type component = TypeUtils.getComponentType(type);
Local T = e.make_local(type);
e.load_this();
e.getfield(getFieldName(i));
e.store_local(T);
e.load_local(T);
e.load_arg(0);
e.load_local(T);
e.load_arg(1);
e.array_load(component);
e.load_local(T);
e.load_arg(1);
e.load_local(T);
e.load_arg(0);
e.array_load(component);
e.array_store(component);
e.array_store(component);
}
e.return_value();
e.end_method();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/ 0000755 0001750 0001750 00000000000 12250627450 020377 5 ustar miguel miguel cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/Proxy.java 0000644 0001750 0001750 00000007213 10066633130 022361 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Member;
import net.sf.cglib.core.CodeGenerationException;
/**
* This class is meant to be used as replacement for
* java.lang.reflect.Proxy
under JDK 1.2. There are some known
* subtle differences:
*
getExceptionTypes
* on the Method
passed to the invoke
method
* are the exact set that can be thrown without resulting in an
* UndeclaredThrowableException
being thrown.
* java.lang.reflect.UndeclaredThrowableException
.
*
* @version $Id: Proxy.java,v 1.6 2004/06/24 21:15:19 herbyderby Exp $
*/
public class Proxy implements Serializable {
protected InvocationHandler h;
private static final CallbackFilter BAD_OBJECT_METHOD_FILTER = new CallbackFilter() {
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;
}
};
protected Proxy(InvocationHandler h) {
Enhancer.registerCallbacks(getClass(), new Callback[]{ h, null });
this.h = h;
}
// private for security of isProxyClass
private static class ProxyImpl extends Proxy {
protected ProxyImpl(InvocationHandler h) {
super(h);
}
}
public static InvocationHandler getInvocationHandler(Object proxy) {
if (!(proxy instanceof ProxyImpl)) {
throw new IllegalArgumentException("Object is not a proxy");
}
return ((Proxy)proxy).h;
}
public static Class getProxyClass(ClassLoader loader, Class[] interfaces) {
Enhancer e = new Enhancer();
e.setSuperclass(ProxyImpl.class);
e.setInterfaces(interfaces);
e.setCallbackTypes(new Class[]{
InvocationHandler.class,
NoOp.class,
});
e.setCallbackFilter(BAD_OBJECT_METHOD_FILTER);
e.setUseFactory(false);
return e.createClass();
}
public static boolean isProxyClass(Class cl) {
return cl.getSuperclass().equals(ProxyImpl.class);
}
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) {
try {
Class clazz = getProxyClass(loader, interfaces);
return clazz.getConstructor(new Class[]{ InvocationHandler.class }).newInstance(new Object[]{ h });
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/MethodInterceptor.java 0000644 0001750 0001750 00000003560 10066633130 024700 0 ustar miguel miguel /*
* Copyright 2002,2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
/**
* General-purpose {@link Enhancer} callback which provides for "around advice".
* @author Juozas Baliuka baliuka@mwm.lt
* @version $Id: MethodInterceptor.java,v 1.8 2004/06/24 21:15:20 herbyderby Exp $
*/
public interface MethodInterceptor
extends Callback
{
/**
* All generated proxied methods call this method instead of the original method.
* The original method may either be invoked by normal reflection using the Method object,
* or by using the MethodProxy (faster).
* @param obj "this", the enhanced object
* @param method intercepted Method
* @param args argument array; primitive types are wrapped
* @param proxy used to invoke super (non-intercepted method); may be called
* as many times as needed
* @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;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/Callback.java 0000644 0001750 0001750 00000001616 10066633130 022735 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
/**
* All callback interfaces used by {@link Enhancer} extend this interface.
* @see MethodInterceptor
* @see NoOp
* @see LazyLoader
* @see Dispatcher
* @see InvocationHandler
* @see FixedValue
*/
public interface Callback
{
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/Dispatcher.java 0000644 0001750 0001750 00000002243 10066633130 023324 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
/**
* Dispatching {@link Enhancer} callback. This is identical to the
* {@link LazyLoader} interface but needs to be separate so that Enhancer
* knows which type of code to generate.
*/
public interface Dispatcher extends Callback {
/**
* Return the object which the original method invocation should
* be dispatched. This method is called for every method invocation.
* @return an object that can invoke the method
*/
Object loadObject() throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/InvocationHandlerGenerator.java 0000644 0001750 0001750 00000005264 10402432050 026512 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import net.sf.cglib.core.*;
import java.util.*;
import org.objectweb.asm.Type;
class InvocationHandlerGenerator
implements CallbackGenerator
{
public static final InvocationHandlerGenerator INSTANCE = new InvocationHandlerGenerator();
private static final Type INVOCATION_HANDLER =
TypeUtils.parseType("net.sf.cglib.proxy.InvocationHandler");
private static final Type UNDECLARED_THROWABLE_EXCEPTION =
TypeUtils.parseType("net.sf.cglib.proxy.UndeclaredThrowableException");
private static final Type METHOD =
TypeUtils.parseType("java.lang.reflect.Method");
private static final Signature INVOKE =
TypeUtils.parseSignature("Object invoke(Object, java.lang.reflect.Method, Object[])");
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);
ce.declare_field(Constants.PRIVATE_FINAL_STATIC, impl.getName(), METHOD, null);
CodeEmitter e = context.beginMethod(ce, method);
Block handler = e.begin_block();
context.emitCallback(e, context.getIndex(method));
e.load_this();
e.getfield(impl.getName());
e.create_arg_array();
e.invoke_interface(INVOCATION_HANDLER, INVOKE);
e.unbox(method.getSignature().getReturnType());
e.return_value();
handler.end();
EmitUtils.wrap_undeclared_throwable(e, handler, method.getExceptionTypes(), UNDECLARED_THROWABLE_EXCEPTION);
e.end_method();
}
}
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);
e.putfield(context.getImplSignature(method).getName());
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/LazyLoader.java 0000644 0001750 0001750 00000002206 10066633130 023303 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
/**
* Lazy-loading {@link Enhancer} callback.
*/
public interface LazyLoader extends Callback {
/**
* Return the object which the original method invocation should be
* dispatched. Called as soon as the first lazily-loaded method in
* the enhanced instance is invoked. The same object is then used
* for every future method call to the proxy instance.
* @return an object that can invoke the method
*/
Object loadObject() throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/MethodProxy.java 0000644 0001750 0001750 00000020651 11132423734 023525 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.sf.cglib.core.AbstractClassGenerator;
import net.sf.cglib.core.CodeGenerationException;
import net.sf.cglib.core.GeneratorStrategy;
import net.sf.cglib.core.NamingPolicy;
import net.sf.cglib.core.Signature;
import net.sf.cglib.reflect.FastClass;
/**
* Classes generated by {@link Enhancer} pass this object to the
* registered {@link MethodInterceptor} objects when an intercepted method is invoked. It can
* be used to either invoke the original method, or call the same method on a different
* object of the same type.
* @version $Id: MethodProxy.java,v 1.16 2009/01/11 20:09:48 herbyderby Exp $
*/
public class MethodProxy {
private Signature sig1;
private Signature sig2;
private CreateInfo createInfo;
private final Object initLock = new Object();
private volatile FastClassInfo fastClassInfo;
/**
* For internal use by {@link Enhancer} only; see the {@link net.sf.cglib.reflect.FastMethod} class
* for similar functionality.
*/
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
MethodProxy proxy = new MethodProxy();
proxy.sig1 = new Signature(name1, desc);
proxy.sig2 = new Signature(name2, desc);
proxy.createInfo = new CreateInfo(c1, c2);
return proxy;
}
private void init()
{
/*
* Using a volatile invariant allows us to initialize the FastClass and
* method index pairs atomically.
*
* Double-checked locking is safe with volatile in Java 5. Before 1.5 this
* code could allow fastClassInfo to be instantiated more than once, which
* appears to be benign.
*/
if (fastClassInfo == null)
{
synchronized (initLock)
{
if (fastClassInfo == null)
{
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
private static class FastClassInfo
{
FastClass f1;
FastClass f2;
int i1;
int i2;
}
private static class CreateInfo
{
Class c1;
Class c2;
NamingPolicy namingPolicy;
GeneratorStrategy strategy;
boolean attemptLoad;
public CreateInfo(Class c1, Class c2)
{
this.c1 = c1;
this.c2 = c2;
AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
if (fromEnhancer != null) {
namingPolicy = fromEnhancer.getNamingPolicy();
strategy = fromEnhancer.getStrategy();
attemptLoad = fromEnhancer.getAttemptLoad();
}
}
}
private static FastClass helper(CreateInfo ci, Class type) {
FastClass.Generator g = new FastClass.Generator();
g.setType(type);
g.setClassLoader(ci.c2.getClassLoader());
g.setNamingPolicy(ci.namingPolicy);
g.setStrategy(ci.strategy);
g.setAttemptLoad(ci.attemptLoad);
return g.create();
}
private MethodProxy() {
}
/**
* Return the signature of the proxied method.
*/
public Signature getSignature() {
return sig1;
}
/**
* Return the name of the synthetic method created by CGLIB which is
* used by {@link #invokeSuper} to invoke the superclass
* (non-intercepted) method implementation. The parameter types are
* the same as the proxied method.
*/
public String getSuperName() {
return sig2.getName();
}
/**
* Return the {@link net.sf.cglib.reflect.FastClass} method index
* for the method used by {@link #invokeSuper}. This index uniquely
* identifies the method within the generated proxy, and therefore
* can be useful to reference external metadata.
* @see #getSuperName
*/
public int getSuperIndex() {
init();
return fastClassInfo.i2;
}
// For testing
FastClass getFastClass() {
init();
return fastClassInfo.f1;
}
// For testing
FastClass getSuperFastClass() {
init();
return fastClassInfo.f2;
}
/**
* Return the MethodProxy
used when intercepting the method
* matching the given signature.
* @param type the class generated by Enhancer
* @param sig the signature to match
* @return the MethodProxy instance, or null if no applicable matching method is found
* @throws IllegalArgumentException if the Class was not created by Enhancer or does not use a MethodInterceptor
*/
public static MethodProxy find(Class type, Signature sig) {
try {
Method m = type.getDeclaredMethod(MethodInterceptorGenerator.FIND_PROXY_NAME,
MethodInterceptorGenerator.FIND_PROXY_TYPES);
return (MethodProxy)m.invoke(null, new Object[]{ sig });
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Class " + type + " does not use a MethodInterceptor");
} catch (IllegalAccessException e) {
throw new CodeGenerationException(e);
} catch (InvocationTargetException e) {
throw new CodeGenerationException(e);
}
}
/**
* Invoke the original method, on a different object of the same type.
* @param obj the compatible object; recursion will result if you use the object passed as the first
* argument to the MethodInterceptor (usually not what you want)
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @see MethodInterceptor#intercept
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an InvocationTargetException
*/
public Object invoke(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f1.invoke(fci.i1, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (IllegalArgumentException e) {
if (fastClassInfo.i1 < 0)
throw new IllegalArgumentException("Protected method: " + sig1);
throw e;
}
}
/**
* Invoke the original (super) method on the specified object.
* @param obj the enhanced object, must be the object passed as the first
* argument to the MethodInterceptor
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @see MethodInterceptor#intercept
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an InvocationTargetException
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/InvocationHandler.java 0000644 0001750 0001750 00000002531 10066633130 024645 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Method;
/**
* {@link java.lang.reflect.InvocationHandler} replacement (unavailable under JDK 1.2).
* This callback type is primarily for use by the {@link Proxy} class but
* may be used with {@link Enhancer} as well.
* @author Neeme Praks neeme@apache.org
* @version $Id: InvocationHandler.java,v 1.3 2004/06/24 21:15:20 herbyderby Exp $
*/
public interface InvocationHandler
extends Callback
{
/**
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object)
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/MethodInterceptorGenerator.java 0000644 0001750 0001750 00000023135 12250627534 026557 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Method;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
class MethodInterceptorGenerator
implements CallbackGenerator
{
public static final MethodInterceptorGenerator INSTANCE = new MethodInterceptorGenerator();
static final String EMPTY_ARGS_NAME = "CGLIB$emptyArgs";
static final String FIND_PROXY_NAME = "CGLIB$findMethodProxy";
static final Class[] FIND_PROXY_TYPES = { Signature.class };
private static final Type ABSTRACT_METHOD_ERROR =
TypeUtils.parseType("AbstractMethodError");
private static final Type METHOD =
TypeUtils.parseType("java.lang.reflect.Method");
private static final Type REFLECT_UTILS =
TypeUtils.parseType("net.sf.cglib.core.ReflectUtils");
private static final Type METHOD_PROXY =
TypeUtils.parseType("net.sf.cglib.proxy.MethodProxy");
private static final Type METHOD_INTERCEPTOR =
TypeUtils.parseType("net.sf.cglib.proxy.MethodInterceptor");
private static final Signature GET_DECLARED_METHODS =
TypeUtils.parseSignature("java.lang.reflect.Method[] getDeclaredMethods()");
private static final Signature GET_DECLARING_CLASS =
TypeUtils.parseSignature("Class getDeclaringClass()");
private static final Signature FIND_METHODS =
TypeUtils.parseSignature("java.lang.reflect.Method[] findMethods(String[], java.lang.reflect.Method[])");
private static final Signature MAKE_PROXY =
new Signature("create", METHOD_PROXY, new Type[]{
Constants.TYPE_CLASS,
Constants.TYPE_CLASS,
Constants.TYPE_STRING,
Constants.TYPE_STRING,
Constants.TYPE_STRING
});
private static final Signature INTERCEPT =
new Signature("intercept", Constants.TYPE_OBJECT, new Type[]{
Constants.TYPE_OBJECT,
METHOD,
Constants.TYPE_OBJECT_ARRAY,
METHOD_PROXY
});
private static final Signature FIND_PROXY =
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(){
public Object transform(Object value) {
return ((MethodInfo)value).getClassInfo();
}
};
private static final Signature CSTRUCT_SIGNATURE =
TypeUtils.parseConstructor("String, String");
private String getMethodField(Signature impl) {
return impl.getName() + "$Method";
}
private String getMethodProxyField(Signature impl) {
return impl.getName() + "$Proxy";
}
public void generate(ClassEmitter ce, Context context, List methods) {
Map sigMap = new HashMap();
for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next();
Signature sig = method.getSignature();
Signature impl = context.getImplSignature(method);
String methodField = getMethodField(impl);
String methodProxyField = getMethodProxyField(impl);
sigMap.put(sig.toString(), methodProxyField);
ce.declare_field(Constants.PRIVATE_FINAL_STATIC, methodField, METHOD, null);
ce.declare_field(Constants.PRIVATE_FINAL_STATIC, methodProxyField, METHOD_PROXY, null);
ce.declare_field(Constants.PRIVATE_FINAL_STATIC, EMPTY_ARGS_NAME, Constants.TYPE_OBJECT_ARRAY, null);
CodeEmitter e;
// access method
e = ce.begin_method(Constants.ACC_FINAL,
impl,
method.getExceptionTypes());
superHelper(e, method, context);
e.return_value();
e.end_method();
// around method
e = context.beginMethod(ce, method);
Label nullInterceptor = e.make_label();
context.emitCallback(e, context.getIndex(method));
e.dup();
e.ifnull(nullInterceptor);
e.load_this();
e.getfield(methodField);
if (sig.getArgumentTypes().length == 0) {
e.getfield(EMPTY_ARGS_NAME);
} else {
e.create_arg_array();
}
e.getfield(methodProxyField);
e.invoke_interface(METHOD_INTERCEPTOR, INTERCEPT);
e.unbox_or_zero(sig.getReturnType());
e.return_value();
e.mark(nullInterceptor);
superHelper(e, method, context);
e.return_value();
e.end_method();
}
generateFindProxy(ce, sigMap);
}
private static void superHelper(CodeEmitter e, MethodInfo method, Context context)
{
if (TypeUtils.isAbstract(method.getModifiers())) {
e.throw_exception(ABSTRACT_METHOD_ERROR, method.toString() + " is abstract" );
} else {
e.load_this();
e.load_args();
context.emitInvoke(e, method);
}
}
public void generateStatic(CodeEmitter e, Context context, List methods) throws Exception {
/* generates:
static {
Class thisClass = Class.forName("NameOfThisClass");
Class cls = Class.forName("java.lang.Object");
String[] sigs = new String[]{ "toString", "()Ljava/lang/String;", ... };
Method[] methods = cls.getDeclaredMethods();
methods = ReflectUtils.findMethods(sigs, methods);
METHOD_0 = methods[0];
CGLIB$ACCESS_0 = MethodProxy.create(cls, thisClass, "()Ljava/lang/String;", "toString", "CGLIB$ACCESS_0");
...
}
*/
e.push(0);
e.newarray();
e.putfield(EMPTY_ARGS_NAME);
Local thisclass = e.make_local();
Local declaringclass = e.make_local();
EmitUtils.load_class_this(e);
e.store_local(thisclass);
Map methodsByClass = CollectionUtils.bucket(methods, METHOD_TO_CLASS);
for (Iterator i = methodsByClass.keySet().iterator(); i.hasNext();) {
ClassInfo classInfo = (ClassInfo)i.next();
List classMethods = (List)methodsByClass.get(classInfo);
e.push(2 * classMethods.size());
e.newarray(Constants.TYPE_STRING);
for (int index = 0; index < classMethods.size(); index++) {
MethodInfo method = (MethodInfo)classMethods.get(index);
Signature sig = method.getSignature();
e.dup();
e.push(2 * index);
e.push(sig.getName());
e.aastore();
e.dup();
e.push(2 * index + 1);
e.push(sig.getDescriptor());
e.aastore();
}
EmitUtils.load_class(e, classInfo.getType());
e.dup();
e.store_local(declaringclass);
e.invoke_virtual(Constants.TYPE_CLASS, GET_DECLARED_METHODS);
e.invoke_static(REFLECT_UTILS, FIND_METHODS);
for (int index = 0; index < classMethods.size(); index++) {
MethodInfo method = (MethodInfo)classMethods.get(index);
Signature sig = method.getSignature();
Signature impl = context.getImplSignature(method);
e.dup();
e.push(index);
e.array_load(METHOD);
e.putfield(getMethodField(impl));
e.load_local(declaringclass);
e.load_local(thisclass);
e.push(sig.getDescriptor());
e.push(sig.getName());
e.push(impl.getName());
e.invoke_static(METHOD_PROXY, MAKE_PROXY);
e.putfield(getMethodProxyField(impl));
}
e.pop();
}
}
public void generateFindProxy(ClassEmitter ce, final Map sigMap) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
FIND_PROXY,
null);
e.load_arg(0);
e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING);
ObjectSwitchCallback callback = new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
e.getfield((String)sigMap.get(key));
e.return_value();
}
public void processDefault() {
e.aconst_null();
e.return_value();
}
};
EmitUtils.string_switch(e,
(String[])sigMap.keySet().toArray(new String[0]),
Constants.SWITCH_STYLE_HASH,
callback);
e.end_method();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/MixinEverythingEmitter.java 0000644 0001750 0001750 00000003475 10066633130 025731 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import net.sf.cglib.core.CollectionUtils;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.RejectModifierPredicate;
import org.objectweb.asm.ClassVisitor;
/**
* @author Chris Nokleberg
* @version $Id: MixinEverythingEmitter.java,v 1.3 2004/06/24 21:15:19 herbyderby Exp $
*/
class MixinEverythingEmitter extends MixinEmitter {
public MixinEverythingEmitter(ClassVisitor v, String className, Class[] classes) {
super(v, className, classes, null);
}
protected Class[] getInterfaces(Class[] classes) {
List list = new ArrayList();
for (int i = 0; i < classes.length; i++) {
ReflectUtils.addAllInterfaces(classes[i], list);
}
return (Class[])list.toArray(new Class[list.size()]);
}
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()]);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/Enhancer.java 0000644 0001750 0001750 00000133376 12250627534 023005 0 ustar miguel miguel /*
* Copyright 2002,2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.Label;
/**
* Generates dynamic subclasses to enable method interception. This
* class started as a substitute for the standard Dynamic Proxy support
* included with JDK 1.3, but one that allowed the proxies to extend a
* concrete base class, in addition to implementing interfaces. The dynamically
* generated subclasses override the non-final methods of the superclass and
* have hooks which callback to user-defined interceptor
* implementations.
*
* The original and most general callback type is the {@link MethodInterceptor}, which * in AOP terms enables "around advice"--that is, you can invoke custom code both before * and after the invocation of the "super" method. In addition you can modify the * arguments before calling the super method, or not call it at all. *
* Although MethodInterceptor
is generic enough to meet any
* interception need, it is often overkill. For simplicity and performance, additional
* specialized callback types, such as {@link LazyLoader} are also available.
* Often a single callback will be used per enhanced class, but you can control
* which callback is used on a per-method basis with a {@link CallbackFilter}.
*
* The most common uses of this class are embodied in the static helper methods. For
* advanced needs, such as customizing the ClassLoader
to use, you should create
* a new instance of Enhancer
. Other classes within CGLIB follow a similar pattern.
*
* All enhanced objects implement the {@link Factory} interface, unless {@link #setUseFactory} is
* used to explicitly disable this feature. The Factory
interface provides an API
* to change the callbacks of an existing object, as well as a faster and easier way to create
* new instances of the same type.
*
* For an almost drop-in replacement for
* java.lang.reflect.Proxy
, see the {@link Proxy} class.
*/
public class Enhancer extends AbstractClassGenerator
{
private static final CallbackFilter ALL_ZERO = new CallbackFilter(){
public int accept(Method method) {
return 0;
}
};
private static final Source SOURCE = new Source(Enhancer.class.getName());
private static final EnhancerKey KEY_FACTORY =
(EnhancerKey)KeyFactory.create(EnhancerKey.class);
private static final String BOUND_FIELD = "CGLIB$BOUND";
private static final String THREAD_CALLBACKS_FIELD = "CGLIB$THREAD_CALLBACKS";
private static final String STATIC_CALLBACKS_FIELD = "CGLIB$STATIC_CALLBACKS";
private static final String SET_THREAD_CALLBACKS_NAME = "CGLIB$SET_THREAD_CALLBACKS";
private static final String SET_STATIC_CALLBACKS_NAME = "CGLIB$SET_STATIC_CALLBACKS";
private static final String CONSTRUCTED_FIELD = "CGLIB$CONSTRUCTED";
private static final Type FACTORY =
TypeUtils.parseType("net.sf.cglib.proxy.Factory");
private static final Type ILLEGAL_STATE_EXCEPTION =
TypeUtils.parseType("IllegalStateException");
private static final Type ILLEGAL_ARGUMENT_EXCEPTION =
TypeUtils.parseType("IllegalArgumentException");
private static final Type THREAD_LOCAL =
TypeUtils.parseType("ThreadLocal");
private static final Type CALLBACK =
TypeUtils.parseType("net.sf.cglib.proxy.Callback");
private static final Type CALLBACK_ARRAY =
Type.getType(Callback[].class);
private static final Signature CSTRUCT_NULL =
TypeUtils.parseConstructor("");
private static final Signature SET_THREAD_CALLBACKS =
new Signature(SET_THREAD_CALLBACKS_NAME, Type.VOID_TYPE, new Type[]{ CALLBACK_ARRAY });
private static final Signature SET_STATIC_CALLBACKS =
new Signature(SET_STATIC_CALLBACKS_NAME, Type.VOID_TYPE, new Type[]{ CALLBACK_ARRAY });
private static final Signature NEW_INSTANCE =
new Signature("newInstance", Constants.TYPE_OBJECT, new Type[]{ CALLBACK_ARRAY });
private static final Signature MULTIARG_NEW_INSTANCE =
new Signature("newInstance", Constants.TYPE_OBJECT, new Type[]{
Constants.TYPE_CLASS_ARRAY,
Constants.TYPE_OBJECT_ARRAY,
CALLBACK_ARRAY,
});
private static final Signature SINGLE_NEW_INSTANCE =
new Signature("newInstance", Constants.TYPE_OBJECT, new Type[]{ CALLBACK });
private static final Signature SET_CALLBACK =
new Signature("setCallback", Type.VOID_TYPE, new Type[]{ Type.INT_TYPE, CALLBACK });
private static final Signature GET_CALLBACK =
new Signature("getCallback", CALLBACK, new Type[]{ Type.INT_TYPE });
private static final Signature SET_CALLBACKS =
new Signature("setCallbacks", Type.VOID_TYPE, new Type[]{ CALLBACK_ARRAY });
private static final Signature GET_CALLBACKS =
new Signature("getCallbacks", CALLBACK_ARRAY, new Type[0]);
private static final Signature THREAD_LOCAL_GET =
TypeUtils.parseSignature("Object get()");
private static final Signature THREAD_LOCAL_SET =
TypeUtils.parseSignature("void set(Object)");
private static final Signature BIND_CALLBACKS =
TypeUtils.parseSignature("void CGLIB$BIND_CALLBACKS(Object)");
/** Internal interface, only public due to ClassLoader issues. */
public interface EnhancerKey {
public Object newInstance(String type,
String[] interfaces,
CallbackFilter filter,
Type[] callbackTypes,
boolean useFactory,
boolean interceptDuringConstruction,
Long serialVersionUID);
}
private Class[] interfaces;
private CallbackFilter filter;
private Callback[] callbacks;
private Type[] callbackTypes;
private boolean classOnly;
private Class superclass;
private Class[] argumentTypes;
private Object[] arguments;
private boolean useFactory = true;
private Long serialVersionUID;
private boolean interceptDuringConstruction = true;
/**
* Create a new Enhancer
. A new Enhancer
* object should be used for each generated object, and should not
* be shared across threads. To create additional instances of a
* generated class, use the Factory
interface.
* @see Factory
*/
public Enhancer() {
super(SOURCE);
}
/**
* Set the class which the generated class will extend. As a convenience,
* if the supplied superclass is actually an interface, setInterfaces
* will be called with the appropriate argument instead.
* A non-interface argument must not be declared as final, and must have an
* accessible constructor.
* @param superclass class to extend or interface to implement
* @see #setInterfaces(Class[])
*/
public void setSuperclass(Class superclass) {
if (superclass != null && superclass.isInterface()) {
setInterfaces(new Class[]{ superclass });
} else if (superclass != null && superclass.equals(Object.class)) {
// affects choice of ClassLoader
this.superclass = null;
} else {
this.superclass = superclass;
}
}
/**
* Set the interfaces to implement. The Factory
interface will
* always be implemented regardless of what is specified here.
* @param interfaces array of interfaces to implement, or null
* @see Factory
*/
public void setInterfaces(Class[] interfaces) {
this.interfaces = interfaces;
}
/**
* Set the {@link CallbackFilter} used to map the generated class' methods
* to a particular callback index.
* New object instances will always use the same mapping, but may use different
* actual callback objects.
* @param filter the callback filter to use when generating a new class
* @see #setCallbacks
*/
public void setCallbackFilter(CallbackFilter filter) {
this.filter = filter;
}
/**
* Set the single {@link Callback} to use.
* Ignored if you use {@link #createClass}.
* @param callback the callback to use for all methods
* @see #setCallbacks
*/
public void setCallback(final Callback callback) {
setCallbacks(new Callback[]{ callback });
}
/**
* Set the array of callbacks to use.
* Ignored if you use {@link #createClass}.
* You must use a {@link CallbackFilter} to specify the index into this
* array for each method in the proxied class.
* @param callbacks the callback array
* @see #setCallbackFilter
* @see #setCallback
*/
public void setCallbacks(Callback[] callbacks) {
if (callbacks != null && callbacks.length == 0) {
throw new IllegalArgumentException("Array cannot be empty");
}
this.callbacks = callbacks;
}
/**
* Set whether the enhanced object instances should implement
* the {@link Factory} interface.
* This was added for tools that need for proxies to be more
* indistinguishable from their targets. Also, in some cases it may
* be necessary to disable the Factory
interface to
* prevent code from changing the underlying callbacks.
* @param useFactory whether to implement Factory
; default is true
*/
public void setUseFactory(boolean useFactory) {
this.useFactory = useFactory;
}
/**
* Set whether methods called from within the proxy's constructer
* will be intercepted. The default value is true. Unintercepted methods
* will call the method of the proxy's base class, if it exists.
* @param interceptDuringConstruction whether to intercept methods called from the constructor
*/
public void setInterceptDuringConstruction(boolean interceptDuringConstruction) {
this.interceptDuringConstruction = interceptDuringConstruction;
}
/**
* Set the single type of {@link Callback} to use.
* This may be used instead of {@link #setCallback} when calling
* {@link #createClass}, since it may not be possible to have
* an array of actual callback instances.
* @param callbackType the type of callback to use for all methods
* @see #setCallbackTypes
*/
public void setCallbackType(Class callbackType) {
setCallbackTypes(new Class[]{ callbackType });
}
/**
* Set the array of callback types to use.
* This may be used instead of {@link #setCallbacks} when calling
* {@link #createClass}, since it may not be possible to have
* an array of actual callback instances.
* You must use a {@link CallbackFilter} to specify the index into this
* array for each method in the proxied class.
* @param callbackTypes the array of callback types
*/
public void setCallbackTypes(Class[] callbackTypes) {
if (callbackTypes != null && callbackTypes.length == 0) {
throw new IllegalArgumentException("Array cannot be empty");
}
this.callbackTypes = CallbackInfo.determineTypes(callbackTypes);
}
/**
* Generate a new class if necessary and uses the specified
* callbacks (if any) to create a new object instance.
* Uses the no-arg constructor of the superclass.
* @return a new instance
*/
public Object create() {
classOnly = false;
argumentTypes = null;
return createHelper();
}
/**
* Generate a new class if necessary and uses the specified
* callbacks (if any) to create a new object instance.
* Uses the constructor of the superclass matching the argumentTypes
* parameter, with the given arguments.
* @param argumentTypes constructor signature
* @param arguments compatible wrapped arguments to pass to constructor
* @return a new instance
*/
public Object create(Class[] argumentTypes, Object[] arguments) {
classOnly = false;
if (argumentTypes == null || arguments == null || argumentTypes.length != arguments.length) {
throw new IllegalArgumentException("Arguments must be non-null and of equal length");
}
this.argumentTypes = argumentTypes;
this.arguments = arguments;
return createHelper();
}
/**
* Generate a new class if necessary and return it without creating a new instance.
* This ignores any callbacks that have been set.
* To create a new instance you will have to use reflection, and methods
* called during the constructor will not be intercepted. To avoid this problem,
* use the multi-arg create
method.
* @see #create(Class[], Object[])
*/
public Class createClass() {
classOnly = true;
return (Class)createHelper();
}
/**
* Insert a static serialVersionUID field into the generated class.
* @param sUID the field value, or null to avoid generating field.
*/
public void setSerialVersionUID(Long sUID) {
serialVersionUID = sUID;
}
private void validate() {
if (classOnly ^ (callbacks == null)) {
if (classOnly) {
throw new IllegalStateException("createClass does not accept callbacks");
} else {
throw new IllegalStateException("Callbacks are required");
}
}
if (classOnly && (callbackTypes == null)) {
throw new IllegalStateException("Callback types are required");
}
if (callbacks != null && callbackTypes != null) {
if (callbacks.length != callbackTypes.length) {
throw new IllegalStateException("Lengths of callback and callback types array must be the same");
}
Type[] check = CallbackInfo.determineTypes(callbacks);
for (int i = 0; i < check.length; i++) {
if (!check[i].equals(callbackTypes[i])) {
throw new IllegalStateException("Callback " + check[i] + " is not assignable to " + callbackTypes[i]);
}
}
} else if (callbacks != null) {
callbackTypes = CallbackInfo.determineTypes(callbacks);
}
if (filter == null) {
if (callbackTypes.length > 1) {
throw new IllegalStateException("Multiple callback types possible but no filter specified");
}
filter = ALL_ZERO;
}
if (interfaces != null) {
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i] == null) {
throw new IllegalStateException("Interfaces cannot be null");
}
if (!interfaces[i].isInterface()) {
throw new IllegalStateException(interfaces[i] + " is not an interface");
}
}
}
}
private Object createHelper() {
validate();
if (superclass != null) {
setNamePrefix(superclass.getName());
} else if (interfaces != null) {
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter,
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID));
}
protected ClassLoader getDefaultClassLoader() {
if (superclass != null) {
return superclass.getClassLoader();
} else if (interfaces != null) {
return interfaces[0].getClassLoader();
} else {
return null;
}
}
private Signature rename(Signature sig, int index) {
return new Signature("CGLIB$" + sig.getName() + "$" + index,
sig.getDescriptor());
}
/**
* Finds all of the methods that will be extended by an
* Enhancer-generated class using the specified superclass and
* interfaces. This can be useful in building a list of Callback
* objects. The methods are added to the end of the given list. Due
* to the subclassing nature of the classes generated by Enhancer,
* the methods are guaranteed to be non-static, non-final, and
* non-private. Each method signature will only occur once, even if
* it occurs in multiple classes.
* @param superclass the class that will be extended, or null
* @param interfaces the list of interfaces that will be implemented, or null
* @param methods the list into which to copy the applicable methods
*/
public static void getMethods(Class superclass, Class[] interfaces, List methods)
{
getMethods(superclass, interfaces, methods, null, null);
}
private static void getMethods(Class superclass, Class[] interfaces, List methods, List interfaceMethods, Set forcePublic)
{
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);
}
}
}
if (interfaceMethods != null) {
if (forcePublic != null) {
forcePublic.addAll(MethodWrapper.createSet(interfaceMethods));
}
methods.addAll(interfaceMethods);
}
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_STATIC));
CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true));
CollectionUtils.filter(methods, new DuplicatesPredicate());
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL));
}
public void generateClass(ClassVisitor v) throws Exception {
Class sc = (superclass == null) ? Object.class : superclass;
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc);
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
filterConstructors(sc, constructors);
// Order is very important: must add superclass, then
// its superclass chain, then each interface and
// its superinterfaces.
List actualMethods = new ArrayList();
List interfaceMethods = new ArrayList();
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);
}
});
ClassEmitter e = new ClassEmitter(v);
e.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
Type.getType(sc),
(useFactory ?
TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
TypeUtils.getTypes(interfaces)),
Constants.SOURCE_FILE);
List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
if (!interceptDuringConstruction) {
e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null);
}
e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
if (serialVersionUID != null) {
e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
}
for (int i = 0; i < callbackTypes.length; i++) {
e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
}
emitMethods(e, methods, actualMethods);
emitConstructors(e, constructorInfo);
emitSetThreadCallbacks(e);
emitSetStaticCallbacks(e);
emitBindCallbacks(e);
if (useFactory) {
int[] keys = getCallbackKeys();
emitNewInstanceCallbacks(e);
emitNewInstanceCallback(e);
emitNewInstanceMultiarg(e, constructorInfo);
emitGetCallback(e, keys);
emitSetCallback(e, keys);
emitGetCallbacks(e);
emitSetCallbacks(e);
}
e.end_class();
}
/**
* Filter the list of constructors from the superclass. The
* constructors which remain will be included in the generated
* class. The default implementation is to filter out all private
* constructors, but subclasses may extend Enhancer to override this
* behavior.
* @param sc the superclass
* @param constructors the list of all declared constructors from the superclass
* @throws IllegalArgumentException if there are no non-private constructors
*/
protected void filterConstructors(Class sc, List constructors) {
CollectionUtils.filter(constructors, new VisibilityPredicate(sc, true));
if (constructors.size() == 0)
throw new IllegalArgumentException("No visible constructors in " + sc);
}
protected Object firstInstance(Class type) throws Exception {
if (classOnly) {
return type;
} else {
return createUsingReflection(type);
}
}
protected Object nextInstance(Object instance) {
Class protoclass = (instance instanceof Class) ? (Class)instance : instance.getClass();
if (classOnly) {
return protoclass;
} else if (instance instanceof Factory) {
if (argumentTypes != null) {
return ((Factory)instance).newInstance(argumentTypes, arguments, callbacks);
} else {
return ((Factory)instance).newInstance(callbacks);
}
} else {
return createUsingReflection(protoclass);
}
}
/**
* Call this method to register the {@link Callback} array to use before
* creating a new instance of the generated class via reflection. If you are using
* an instance of Enhancer
or the {@link Factory} interface to create
* new instances, this method is unnecessary. Its primary use is for when you want to
* cache and reuse a generated class yourself, and the generated class does
* not implement the {@link Factory} interface.
*
* Note that this method only registers the callbacks on the current thread. * If you want to register callbacks for instances created by multiple threads, * use {@link #registerStaticCallbacks}. *
* The registered callbacks are overwritten and subsequently cleared
* when calling any of the
* Delegates are a typesafe pointer to another method. Since Java does not
* have language support for such a construct, this utility will construct
* a proxy that forwards method calls to any method with the same signature.
* This utility is inspired in part by the C# delegate mechanism. We
* implemented it in a Java-centric manner.
*
* Any interface with one method can become the interface for a delegate.
* Consider the example below:
*
* The interface above is an example of an interface that can become a
* delegate. It has only one method, and the interface is public. In
* order to create a delegate for that method, all we have to do is
* call
* By themselves, delegates don't do much. Their true power lies in the fact that
* they can be treated like objects, and passed to other methods. In fact that is
* one of the key building blocks of building Intelligent Agents which in tern are
* the foundation of artificial intelligence. In the above program, we could have
* easily created the delegate to match the static
* Another key use for Delegates is to register event listeners. It is much easier
* to have all the code for your events separated out into methods instead of individual
* classes. One of the ways Java gets around that is to create anonymous classes.
* They are particularly troublesome because many Debuggers do not know what to do
* with them. Anonymous classes tend to duplicate alot of code as well. We can
* use any interface with one declared method to forward events to any method that
* matches the signature (although the method name can be different).
*
* Classes are cached per-
* To generate a
* Once you have made a
* Note:
*
* This is composed of a prefix based on the name of the superclass, a fixed
* string incorporating the CGLIB class responsible for generation, and a
* hashcode derived from the parameters used to create the object. If the same
* name has been previously been used in the same create
methods (such as
* {@link #create}), or any {@link Factory} newInstance
method.
* Otherwise they are not cleared, and you should be careful to set them
* back to null
after creating new instances via reflection if
* memory leakage is a concern.
* @param generatedClass a class previously created by {@link Enhancer}
* @param callbacks the array of callbacks to use when instances of the generated
* class are created
* @see #setUseFactory
*/
public static void registerCallbacks(Class generatedClass, Callback[] callbacks) {
setThreadCallbacks(generatedClass, callbacks);
}
/**
* Similar to {@link #registerCallbacks}, but suitable for use
* when multiple threads will be creating instances of the generated class.
* The thread-level callbacks will always override the static callbacks.
* Static callbacks are never cleared.
* @param generatedClass a class previously created by {@link Enhancer}
* @param callbacks the array of callbacks to use when instances of the generated
* class are created
*/
public static void registerStaticCallbacks(Class generatedClass, Callback[] callbacks) {
setCallbacksHelper(generatedClass, callbacks, SET_STATIC_CALLBACKS_NAME);
}
/**
* Determine if a class was generated using Enhancer
.
* @param type any class
* @return whether the class was generated using Enhancer
*/
public static boolean isEnhanced(Class type) {
try {
getCallbacksSetter(type, SET_THREAD_CALLBACKS_NAME);
return true;
} catch (NoSuchMethodException e) {
return false;
}
}
private static void setThreadCallbacks(Class type, Callback[] callbacks) {
setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);
}
private static void setCallbacksHelper(Class type, Callback[] callbacks, String methodName) {
// TODO: optimize
try {
Method setter = getCallbacksSetter(type, methodName);
setter.invoke(null, new Object[]{ callbacks });
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(type + " is not an enhanced class");
} catch (IllegalAccessException e) {
throw new CodeGenerationException(e);
} catch (InvocationTargetException e) {
throw new CodeGenerationException(e);
}
}
private static Method getCallbacksSetter(Class type, String methodName) throws NoSuchMethodException {
return type.getDeclaredMethod(methodName, new Class[]{ Callback[].class });
}
private Object createUsingReflection(Class type) {
setThreadCallbacks(type, callbacks);
try{
if (argumentTypes != null) {
return ReflectUtils.newInstance(type, argumentTypes, arguments);
} else {
return ReflectUtils.newInstance(type);
}
}finally{
// clear thread callbacks to allow them to be gc'd
setThreadCallbacks(type, null);
}
}
/**
* Helper method to create an intercepted object.
* For finer control over the generated instance, use a new instance of Enhancer
* instead of this static method.
* @param type class to extend or interface to implement
* @param callback the callback to use for all methods
*/
public static Object create(Class type, Callback callback) {
Enhancer e = new Enhancer();
e.setSuperclass(type);
e.setCallback(callback);
return e.create();
}
/**
* Helper method to create an intercepted object.
* For finer control over the generated instance, use a new instance of Enhancer
* instead of this static method.
* @param type class to extend or interface to implement
* @param interfaces array of interfaces to implement, or null
* @param callback the callback to use for all methods
*/
public static Object create(Class superclass, Class interfaces[], Callback callback) {
Enhancer e = new Enhancer();
e.setSuperclass(superclass);
e.setInterfaces(interfaces);
e.setCallback(callback);
return e.create();
}
/**
* Helper method to create an intercepted object.
* For finer control over the generated instance, use a new instance of Enhancer
* instead of this static method.
* @param type class to extend or interface to implement
* @param interfaces array of interfaces to implement, or null
* @param filter the callback filter to use when generating a new class
* @param callbacks callback implementations to use for the enhanced object
*/
public static Object create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) {
Enhancer e = new Enhancer();
e.setSuperclass(superclass);
e.setInterfaces(interfaces);
e.setCallbackFilter(filter);
e.setCallbacks(callbacks);
return e.create();
}
private void emitConstructors(ClassEmitter ce, List constructors) {
boolean seenNull = false;
for (Iterator it = constructors.iterator(); it.hasNext();) {
MethodInfo constructor = (MethodInfo)it.next();
CodeEmitter e = EmitUtils.begin_method(ce, constructor, Constants.ACC_PUBLIC);
e.load_this();
e.dup();
e.load_args();
Signature sig = constructor.getSignature();
seenNull = seenNull || sig.getDescriptor().equals("()V");
e.super_invoke_constructor(sig);
e.invoke_static_this(BIND_CALLBACKS);
if (!interceptDuringConstruction) {
e.load_this();
e.push(1);
e.putfield(CONSTRUCTED_FIELD);
}
e.return_value();
e.end_method();
}
if (!classOnly && !seenNull && arguments == null)
throw new IllegalArgumentException("Superclass has no null constructors but no arguments were given");
}
private int[] getCallbackKeys() {
int[] keys = new int[callbackTypes.length];
for (int i = 0; i < callbackTypes.length; i++) {
keys[i] = i;
}
return keys;
}
private void emitGetCallback(ClassEmitter ce, int[] keys) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, GET_CALLBACK, null);
e.load_this();
e.invoke_static_this(BIND_CALLBACKS);
e.load_this();
e.load_arg(0);
e.process_switch(keys, new ProcessSwitchCallback() {
public void processCase(int key, Label end) {
e.getfield(getCallbackField(key));
e.goTo(end);
}
public void processDefault() {
e.pop(); // stack height
e.aconst_null();
}
});
e.return_value();
e.end_method();
}
private void emitSetCallback(ClassEmitter ce, int[] keys) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SET_CALLBACK, null);
e.load_arg(0);
e.process_switch(keys, new ProcessSwitchCallback() {
public void processCase(int key, Label end) {
e.load_this();
e.load_arg(1);
e.checkcast(callbackTypes[key]);
e.putfield(getCallbackField(key));
e.goTo(end);
}
public void processDefault() {
// TODO: error?
}
});
e.return_value();
e.end_method();
}
private void emitSetCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SET_CALLBACKS, null);
e.load_this();
e.load_arg(0);
for (int i = 0; i < callbackTypes.length; i++) {
e.dup2();
e.aaload(i);
e.checkcast(callbackTypes[i]);
e.putfield(getCallbackField(i));
}
e.return_value();
e.end_method();
}
private void emitGetCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, GET_CALLBACKS, null);
e.load_this();
e.invoke_static_this(BIND_CALLBACKS);
e.load_this();
e.push(callbackTypes.length);
e.newarray(CALLBACK);
for (int i = 0; i < callbackTypes.length; i++) {
e.dup();
e.push(i);
e.load_this();
e.getfield(getCallbackField(i));
e.aastore();
}
e.return_value();
e.end_method();
}
private void emitNewInstanceCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
e.load_arg(0);
e.invoke_static_this(SET_THREAD_CALLBACKS);
emitCommonNewInstance(e);
}
private void emitCommonNewInstance(CodeEmitter e) {
e.new_instance_this();
e.dup();
e.invoke_constructor_this();
e.aconst_null();
e.invoke_static_this(SET_THREAD_CALLBACKS);
e.return_value();
e.end_method();
}
private void emitNewInstanceCallback(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SINGLE_NEW_INSTANCE, null);
switch (callbackTypes.length) {
case 0:
// TODO: make sure Callback is null
break;
case 1:
// for now just make a new array; TODO: optimize
e.push(1);
e.newarray(CALLBACK);
e.dup();
e.push(0);
e.load_arg(0);
e.aastore();
e.invoke_static_this(SET_THREAD_CALLBACKS);
break;
default:
e.throw_exception(ILLEGAL_STATE_EXCEPTION, "More than one callback object required");
}
emitCommonNewInstance(e);
}
private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, MULTIARG_NEW_INSTANCE, null);
e.load_arg(2);
e.invoke_static_this(SET_THREAD_CALLBACKS);
e.new_instance_this();
e.dup();
e.load_arg(0);
EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
MethodInfo constructor = (MethodInfo)key;
Type types[] = constructor.getSignature().getArgumentTypes();
for (int i = 0; i < types.length; i++) {
e.load_arg(1);
e.push(i);
e.aaload();
e.unbox(types[i]);
}
e.invoke_constructor_this(constructor.getSignature());
e.goTo(end);
}
public void processDefault() {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found");
}
});
e.aconst_null();
e.invoke_static_this(SET_THREAD_CALLBACKS);
e.return_value();
e.end_method();
}
private void emitMethods(final ClassEmitter ce, List methods, List actualMethods) {
CallbackGenerator[] generators = CallbackInfo.getGenerators(callbackTypes);
Map groups = new HashMap();
final Map indexes = new HashMap();
final Map originalModifiers = new HashMap();
final Map positions = CollectionUtils.getIndexMap(methods);
final Map declToBridge = new HashMap();
Iterator it1 = methods.iterator();
Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null;
while (it1.hasNext()) {
MethodInfo method = (MethodInfo)it1.next();
Method actualMethod = (it2 != null) ? (Method)it2.next() : null;
int index = filter.accept(actualMethod);
if (index >= callbackTypes.length) {
throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index);
}
originalModifiers.put(method, new Integer((actualMethod != null) ? actualMethod.getModifiers() : method.getModifiers()));
indexes.put(method, new Integer(index));
List group = (List)groups.get(generators[index]);
if (group == null) {
groups.put(generators[index], group = new ArrayList(methods.size()));
}
group.add(method);
// Optimization: build up a map of Class -> bridge methods in class
// so that we can look up all the bridge methods in one pass for a class.
if (TypeUtils.isBridge(actualMethod.getModifiers())) {
Set bridges = (Set)declToBridge.get(actualMethod.getDeclaringClass());
if (bridges == null) {
bridges = new HashSet();
declToBridge.put(actualMethod.getDeclaringClass(), bridges);
}
bridges.add(method.getSignature());
}
}
final Map bridgeToTarget = new BridgeMethodResolver(declToBridge).resolveAll();
Set seenGen = new HashSet();
CodeEmitter se = ce.getStaticHook();
se.new_instance(THREAD_LOCAL);
se.dup();
se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL);
se.putfield(THREAD_CALLBACKS_FIELD);
final Object[] state = new Object[1];
CallbackGenerator.Context context = new CallbackGenerator.Context() {
public ClassLoader getClassLoader() {
return Enhancer.this.getClassLoader();
}
public int getOriginalModifiers(MethodInfo method) {
return ((Integer)originalModifiers.get(method)).intValue();
}
public int getIndex(MethodInfo method) {
return ((Integer)indexes.get(method)).intValue();
}
public void emitCallback(CodeEmitter e, int index) {
emitCurrentCallback(e, index);
}
public Signature getImplSignature(MethodInfo method) {
return rename(method.getSignature(), ((Integer)positions.get(method)).intValue());
}
public void emitInvoke(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
// a super, because super may itself be using super, which would bypass
// any proxies on the target.
Signature bridgeTarget = (Signature)bridgeToTarget.get(method.getSignature());
if (bridgeTarget != null) {
// TODO: this assumes that the target has wider or the same type
// parameters than the current.
// In reality this should always be true because otherwise we wouldn't
// have had a bridge doing an invokespecial.
// If it isn't true, we would need to checkcast each argument
// against the target's argument types
e.invoke_virtual_this(bridgeTarget);
Type retType = method.getSignature().getReturnType();
// Not necessary to cast if the target & bridge have
// the same return type.
// (This conveniently includes void and primitive types,
// which would fail if casted. It's not possible to
// covariant from boxed to unbox (or vice versa), so no having
// to box/unbox for bridges).
// TODO: It also isn't necessary to checkcast if the return is
// assignable from the target. (This would happen if a subclass
// used covariant returns to narrow the return type within a bridge
// method.)
if (!retType.equals(bridgeTarget.getReturnType())) {
e.checkcast(retType);
}
} else {
e.super_invoke(method.getSignature());
}
}
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
if (!interceptDuringConstruction &&
!TypeUtils.isAbstract(method.getModifiers())) {
Label constructed = e.make_label();
e.load_this();
e.getfield(CONSTRUCTED_FIELD);
e.if_jump(e.NE, constructed);
e.load_this();
e.load_args();
e.super_invoke();
e.return_value();
e.mark(constructed);
}
return e;
}
};
for (int i = 0; i < callbackTypes.length; i++) {
CallbackGenerator gen = generators[i];
if (!seenGen.contains(gen)) {
seenGen.add(gen);
final List fmethods = (List)groups.get(gen);
if (fmethods != null) {
try {
gen.generate(ce, context, fmethods);
gen.generateStatic(se, context, fmethods);
} catch (RuntimeException x) {
throw x;
} catch (Exception x) {
throw new CodeGenerationException(x);
}
}
}
}
se.return_value();
se.end_method();
}
private void emitSetThreadCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
SET_THREAD_CALLBACKS,
null);
e.getfield(THREAD_CALLBACKS_FIELD);
e.load_arg(0);
e.invoke_virtual(THREAD_LOCAL, THREAD_LOCAL_SET);
e.return_value();
e.end_method();
}
private void emitSetStaticCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
SET_STATIC_CALLBACKS,
null);
e.load_arg(0);
e.putfield(STATIC_CALLBACKS_FIELD);
e.return_value();
e.end_method();
}
private void emitCurrentCallback(CodeEmitter e, int index) {
e.load_this();
e.getfield(getCallbackField(index));
e.dup();
Label end = e.make_label();
e.ifnonnull(end);
e.pop(); // stack height
e.load_this();
e.invoke_static_this(BIND_CALLBACKS);
e.load_this();
e.getfield(getCallbackField(index));
e.mark(end);
}
private void emitBindCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.PRIVATE_FINAL_STATIC,
BIND_CALLBACKS,
null);
Local me = e.make_local();
e.load_arg(0);
e.checkcast_this();
e.store_local(me);
Label end = e.make_label();
e.load_local(me);
e.getfield(BOUND_FIELD);
e.if_jump(e.NE, end);
e.load_local(me);
e.push(1);
e.putfield(BOUND_FIELD);
e.getfield(THREAD_CALLBACKS_FIELD);
e.invoke_virtual(THREAD_LOCAL, THREAD_LOCAL_GET);
e.dup();
Label found_callback = e.make_label();
e.ifnonnull(found_callback);
e.pop();
e.getfield(STATIC_CALLBACKS_FIELD);
e.dup();
e.ifnonnull(found_callback);
e.pop();
e.goTo(end);
e.mark(found_callback);
e.checkcast(CALLBACK_ARRAY);
e.load_local(me);
e.swap();
for (int i = callbackTypes.length - 1; i >= 0; i--) {
if (i != 0) {
e.dup2();
}
e.aaload(i);
e.checkcast(callbackTypes[i]);
e.putfield(getCallbackField(i));
}
e.mark(end);
e.return_value();
e.end_method();
}
private static String getCallbackField(int index) {
return "CGLIB$CALLBACK_" + index;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/MixinBeanEmitter.java 0000644 0001750 0001750 00000002460 10066633130 024443 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import org.objectweb.asm.ClassVisitor;
/**
* @author Chris Nokleberg
* @version $Id: MixinBeanEmitter.java,v 1.2 2004/06/24 21:15:20 herbyderby Exp $
*/
class MixinBeanEmitter extends MixinEmitter {
public MixinBeanEmitter(ClassVisitor v, String className, Class[] classes) {
super(v, className, classes, null);
}
protected Class[] getInterfaces(Class[] classes) {
return null;
}
protected Method[] getMethods(Class type) {
return ReflectUtils.getPropertyMethods(ReflectUtils.getBeanProperties(type), true, true);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/CallbackGenerator.java 0000644 0001750 0001750 00000002503 12250620400 024571 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.util.List;
import net.sf.cglib.core.*;
interface CallbackGenerator
{
void generate(ClassEmitter ce, Context context, List methods) throws Exception;
void generateStatic(CodeEmitter e, Context context, List methods) throws Exception;
interface Context
{
ClassLoader getClassLoader();
CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method);
int getOriginalModifiers(MethodInfo method);
int getIndex(MethodInfo method);
void emitCallback(CodeEmitter ce, int index);
Signature getImplSignature(MethodInfo method);
void emitInvoke(CodeEmitter e, MethodInfo method);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/ProxyRefDispatcher.java 0000644 0001750 0001750 00000002332 10156243316 025025 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
/**
* Dispatching {@link Enhancer} callback. This is the same as the
* {@link Dispatcher} except for the addition of an argument
* which references the proxy object.
*/
public interface ProxyRefDispatcher extends Callback {
/**
* Return the object which the original method invocation should
* be dispatched. This method is called for every method invocation.
* @param proxy a reference to the proxy (generated) object
* @return an object that can invoke the method
*/
Object loadObject(Object proxy) throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/Mixin.java 0000644 0001750 0001750 00000020414 10316221024 022313 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
/**
* Mixin
allows
* multiple objects to be combined into a single larger object. The
* methods in the generated object simply call the original methods in the
* underlying "delegate" objects.
* @author Chris Nokleberg
* @version $Id: Mixin.java,v 1.7 2005/09/27 11:42:27 baliuka Exp $
*/
abstract public class Mixin {
private static final MixinKey KEY_FACTORY =
(MixinKey)KeyFactory.create(MixinKey.class, KeyFactory.CLASS_BY_NAME);
private static final Map ROUTE_CACHE = Collections.synchronizedMap(new HashMap());
public static final int STYLE_INTERFACES = 0;
public static final int STYLE_BEANS = 1;
public static final int STYLE_EVERYTHING = 2;
interface MixinKey {
public Object newInstance(int style, String[] classes, int[] route);
}
abstract public Mixin newInstance(Object[] delegates);
/**
* Helper method to create an interface mixin. For finer control over the
* generated instance, use a new instance of Mixin
* instead of this static method.
* TODO
*/
public static Mixin create(Object[] delegates) {
Generator gen = new Generator();
gen.setDelegates(delegates);
return gen.create();
}
/**
* Helper method to create an interface mixin. For finer control over the
* generated instance, use a new instance of Mixin
* instead of this static method.
* TODO
*/
public static Mixin create(Class[] interfaces, Object[] delegates) {
Generator gen = new Generator();
gen.setClasses(interfaces);
gen.setDelegates(delegates);
return gen.create();
}
public static Mixin createBean(Object[] beans) {
return createBean(null, beans);
}
/**
* Helper method to create a bean mixin. For finer control over the
* generated instance, use a new instance of Mixin
* instead of this static method.
* TODO
*/
public static Mixin createBean(ClassLoader loader,Object[] beans) {
Generator gen = new Generator();
gen.setStyle(STYLE_BEANS);
gen.setDelegates(beans);
gen.setClassLoader(loader);
return gen.create();
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(Mixin.class.getName());
private Class[] classes;
private Object[] delegates;
private int style = STYLE_INTERFACES;
private int[] route;
public Generator() {
super(SOURCE);
}
protected ClassLoader getDefaultClassLoader() {
return classes[0].getClassLoader(); // is this right?
}
public void setStyle(int style) {
switch (style) {
case STYLE_INTERFACES:
case STYLE_BEANS:
case STYLE_EVERYTHING:
this.style = style;
break;
default:
throw new IllegalArgumentException("Unknown mixin style: " + style);
}
}
public void setClasses(Class[] classes) {
this.classes = classes;
}
public void setDelegates(Object[] delegates) {
this.delegates = delegates;
}
public Mixin create() {
if (classes == null && delegates == null) {
throw new IllegalStateException("Either classes or delegates must be set");
}
switch (style) {
case STYLE_INTERFACES:
if (classes == null) {
Route r = route(delegates);
classes = r.classes;
route = r.route;
}
break;
case STYLE_BEANS:
// fall-through
case STYLE_EVERYTHING:
if (classes == null) {
classes = ReflectUtils.getClasses(delegates);
} else {
if (delegates != null) {
Class[] temp = ReflectUtils.getClasses(delegates);
if (classes.length != temp.length) {
throw new IllegalStateException("Specified classes are incompatible with delegates");
}
for (int i = 0; i < classes.length; i++) {
if (!classes[i].isAssignableFrom(temp[i])) {
throw new IllegalStateException("Specified class " + classes[i] + " is incompatible with delegate class " + temp[i] + " (index " + i + ")");
}
}
}
}
}
setNamePrefix(classes[ReflectUtils.findPackageProtected(classes)].getName());
return (Mixin)super.create(KEY_FACTORY.newInstance(style, ReflectUtils.getNames( classes ), route));
}
public void generateClass(ClassVisitor v) {
switch (style) {
case STYLE_INTERFACES:
new MixinEmitter(v, getClassName(), classes, route);
break;
case STYLE_BEANS:
new MixinBeanEmitter(v, getClassName(), classes);
break;
case STYLE_EVERYTHING:
new MixinEverythingEmitter(v, getClassName(), classes);
break;
}
}
protected Object firstInstance(Class type) {
return ((Mixin)ReflectUtils.newInstance(type)).newInstance(delegates);
}
protected Object nextInstance(Object instance) {
return ((Mixin)instance).newInstance(delegates);
}
}
public static Class[] getClasses(Object[] delegates) {
return (Class[])route(delegates).classes.clone();
}
// public static int[] getRoute(Object[] delegates) {
// return (int[])route(delegates).route.clone();
// }
private static Route route(Object[] delegates) {
Object key = ClassesKey.create(delegates);
Route route = (Route)ROUTE_CACHE.get(key);
if (route == null) {
ROUTE_CACHE.put(key, route = new Route(delegates));
}
return route;
}
private static class Route
{
private Class[] classes;
private int[] route;
Route(Object[] delegates) {
Map map = new HashMap();
ArrayList collect = new ArrayList();
for (int i = 0; i < delegates.length; i++) {
Class delegate = delegates[i].getClass();
collect.clear();
ReflectUtils.addAllInterfaces(delegate, collect);
for (Iterator it = collect.iterator(); it.hasNext();) {
Class iface = (Class)it.next();
if (!map.containsKey(iface)) {
map.put(iface, new Integer(i));
}
}
}
classes = new Class[map.size()];
route = new int[map.size()];
int index = 0;
for (Iterator it = map.keySet().iterator(); it.hasNext();) {
Class key = (Class)it.next();
classes[index] = key;
route[index] = ((Integer)map.get(key)).intValue();
index++;
}
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/BridgeMethodResolver.java 0000644 0001750 0001750 00000010536 11760000000 025303 0 ustar miguel miguel /*
* Copyright 2011 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.sf.cglib.core.Signature;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Uses bytecode reflection to figure out the targets of all bridge methods
* that use invokespecial, so that we can later rewrite them to use invokevirtual.
*
* @author sberlin@gmail.com (Sam Berlin)
*/
class BridgeMethodResolver {
private final Map/* NoOp
callback.
*/
public static final NoOp INSTANCE = new NoOp() { };
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/UndeclaredThrowableException.java 0000644 0001750 0001750 00000002326 10066633130 027035 0 ustar miguel miguel /*
* Copyright 2002,2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import net.sf.cglib.core.CodeGenerationException;
/**
* Used by {@link Proxy} as a replacement for java.lang.reflect.UndeclaredThrowableException
.
* @author Juozas Baliuka
*/
public class UndeclaredThrowableException extends CodeGenerationException {
/**
* Creates a new instance of UndeclaredThrowableException
without detail message.
*/
public UndeclaredThrowableException(Throwable t) {
super(t);
}
public Throwable getUndeclaredThrowable() {
return getCause();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/MixinEmitter.java 0000644 0001750 0001750 00000006341 10474375326 023674 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Method;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
/**
* @author Chris Nokleberg
* @version $Id: MixinEmitter.java,v 1.9 2006/08/27 21:04:37 herbyderby Exp $
*/
class MixinEmitter extends ClassEmitter {
private static final String FIELD_NAME = "CGLIB$DELEGATES";
private static final Signature CSTRUCT_OBJECT_ARRAY =
TypeUtils.parseConstructor("Object[]");
private static final Type MIXIN =
TypeUtils.parseType("net.sf.cglib.proxy.Mixin");
private static final Signature NEW_INSTANCE =
new Signature("newInstance", MIXIN, new Type[]{ Constants.TYPE_OBJECT_ARRAY });
public MixinEmitter(ClassVisitor v, String className, Class[] classes, int[] route) {
super(v);
begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
className,
MIXIN,
TypeUtils.getTypes(getInterfaces(classes)),
Constants.SOURCE_FILE);
EmitUtils.null_constructor(this);
EmitUtils.factory_method(this, NEW_INSTANCE);
declare_field(Constants.ACC_PRIVATE, FIELD_NAME, Constants.TYPE_OBJECT_ARRAY, null);
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null);
e.load_this();
e.super_invoke_constructor();
e.load_this();
e.load_arg(0);
e.putfield(FIELD_NAME);
e.return_value();
e.end_method();
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]);
e = EmitUtils.begin_method(this, method, Constants.ACC_PUBLIC);
e.load_this();
e.getfield(FIELD_NAME);
e.aaload((route != null) ? route[i] : i);
e.checkcast(method.getClassInfo().getType());
e.load_args();
e.invoke(method);
e.return_value();
e.end_method();
}
}
}
end_class();
}
protected Class[] getInterfaces(Class[] classes) {
return classes;
}
protected Method[] getMethods(Class type) {
return type.getMethods();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/InterfaceMaker.java 0000644 0001750 0001750 00000010235 10402432050 024106 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.*;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
/**
* Generates new interfaces at runtime.
* By passing a generated interface to the Enhancer's list of interfaces to
* implement, you can make your enhanced classes handle an arbitrary set
* of method signatures.
* @author Chris Nokleberg
* @version $Id: InterfaceMaker.java,v 1.4 2006/03/05 02:43:19 herbyderby Exp $
*/
public class InterfaceMaker extends AbstractClassGenerator
{
private static final Source SOURCE = new Source(InterfaceMaker.class.getName());
private Map signatures = new HashMap();
/**
* Create a new InterfaceMaker
. A new InterfaceMaker
* object should be used for each generated interface, and should not
* be shared across threads.
*/
public InterfaceMaker() {
super(SOURCE);
}
/**
* Add a method signature to the interface.
* @param sig the method signature to add to the interface
* @param exceptions an array of exception types to declare for the method
*/
public void add(Signature sig, Type[] exceptions) {
signatures.put(sig, exceptions);
}
/**
* Add a method signature to the interface. The method modifiers are ignored,
* since interface methods are by definition abstract and public.
* @param method the method to add to the interface
*/
public void add(Method method) {
add(ReflectUtils.getSignature(method),
ReflectUtils.getExceptionTypes(method));
}
/**
* Add all the public methods in the specified class.
* Methods from superclasses are included, except for methods declared in the base
* Object class (e.g. getClass
, equals
, hashCode
).
* @param class the class containing the methods to add to the interface
*/
public void add(Class clazz) {
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (!m.getDeclaringClass().getName().equals("java.lang.Object")) {
add(m);
}
}
}
/**
* Create an interface using the current set of method signatures.
*/
public Class create() {
setUseCache(false);
return (Class)super.create(this);
}
protected ClassLoader getDefaultClassLoader() {
return null;
}
protected Object firstInstance(Class type) {
return type;
}
protected Object nextInstance(Object instance) {
throw new IllegalStateException("InterfaceMaker does not cache");
}
public void generateClass(ClassVisitor v) throws Exception {
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC | Constants.ACC_INTERFACE,
getClassName(),
null,
null,
Constants.SOURCE_FILE);
for (Iterator it = signatures.keySet().iterator(); it.hasNext();) {
Signature sig = (Signature)it.next();
Type[] exceptions = (Type[])signatures.get(sig);
ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT,
sig,
exceptions).end_method();
}
ce.end_class();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/NoOpGenerator.java 0000644 0001750 0001750 00000003177 12250627534 023777 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.util.Iterator;
import java.util.List;
import net.sf.cglib.core.*;
class NoOpGenerator
implements CallbackGenerator
{
public static final NoOpGenerator INSTANCE = new NoOpGenerator();
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()) || (
TypeUtils.isProtected(context.getOriginalModifiers(method)) &&
TypeUtils.isPublic(method.getModifiers()))) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
e.load_this();
e.load_args();
context.emitInvoke(e, method);
e.return_value();
e.end_method();
}
}
}
public void generateStatic(CodeEmitter e, Context context, List methods) { }
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/FixedValueGenerator.java 0000644 0001750 0001750 00000003247 10162421562 025147 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Type;
class FixedValueGenerator implements CallbackGenerator {
public static final FixedValueGenerator INSTANCE = new FixedValueGenerator();
private static final Type FIXED_VALUE =
TypeUtils.parseType("net.sf.cglib.proxy.FixedValue");
private static final Signature LOAD_OBJECT =
TypeUtils.parseSignature("Object loadObject()");
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);
context.emitCallback(e, context.getIndex(method));
e.invoke_interface(FIXED_VALUE, LOAD_OBJECT);
e.unbox_or_zero(e.getReturnType());
e.return_value();
e.end_method();
}
}
public void generateStatic(CodeEmitter e, Context context, List methods) { }
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/CallbackFilter.java 0000644 0001750 0001750 00000003161 10066633130 024100 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import java.lang.reflect.Method;
/**
* Map methods of subclasses generated by {@link Enhancer} to a particular
* callback. The type of the callbacks chosen for each method affects
* the bytecode generated for that method in the subclass, and cannot
* change for the life of the class.
*/
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,
*/
int accept(Method method);
/**
* The CallbackFilter
in use affects which cached class
* the Enhancer
will use, so this is a reminder that
* you should correctly implement equals
and
* hashCode
for custom CallbackFilter
* implementations in order to improve performance.
*/
boolean equals(Object o);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/Factory.java 0000644 0001750 0001750 00000005756 10066633130 022661 0 ustar miguel miguel /*
* Copyright 2002,2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
/**
* All enhanced instances returned by the {@link Enhancer} class implement this interface.
* Using this interface for new instances is faster than going through the Enhancer
* interface or using reflection. In addition, to intercept methods called during
* object construction you must use these methods instead of reflection.
* @author Juozas Baliuka baliuka@mwm.lt
* @version $Id: Factory.java,v 1.13 2004/06/24 21:15:20 herbyderby Exp $
*/
public interface Factory {
/**
* Creates new instance of the same type, using the no-arg constructor.
* The class of this object must have been created using a single Callback type.
* 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);
/**
* Creates a new instance of the same type, using the constructor
* matching the given signature.
* @param types the constructor argument types
* @param args the constructor arguments
* @param callbacks the new interceptor(s) to use
* @return new instance of the same type
*/
Object newInstance(Class[] types, Object[] args, Callback[] callbacks);
/**
* Return the Callback
implementation at the specified index.
* @param index the callback index
* @return the callback implementation
*/
Callback getCallback(int index);
/**
* Set the callback for this object for the given type.
* @param index the callback index to replace
* @param callback the new callback
*/
void setCallback(int index, Callback callback);
/**
* Replace all of the callbacks for this object at once.
* @param callbacks the new callbacks(s) to use
*/
void setCallbacks(Callback[] callbacks);
/**
* Get the current set of callbacks for ths object.
* @return a new array instance
*/
Callback[] getCallbacks();
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/proxy/CallbackHelper.java 0000644 0001750 0001750 00000006721 10066633130 024077 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.proxy;
import net.sf.cglib.core.ReflectUtils;
import java.lang.reflect.Method;
import java.util.*;
/**
* @version $Id: CallbackHelper.java,v 1.2 2004/06/24 21:15:20 herbyderby Exp $
*/
abstract public class CallbackHelper
implements CallbackFilter
{
private Map methodMap = new HashMap();
private List callbacks = new ArrayList();
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)
throw new IllegalStateException("getCallback cannot return null");
boolean isCallback = callback instanceof Callback;
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))
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 = new Integer(callbacks.size());
indexes.put(callback, index);
}
methodMap.put(method, index);
callbacks.add(callback);
}
}
abstract protected Object getCallback(Method method);
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 {
throw new IllegalStateException("getCallback returned classes, not callbacks; call getCallbackTypes instead");
}
}
public Class[] getCallbackTypes()
{
if (callbacks.size() == 0)
return new Class[0];
if (callbacks.get(0) instanceof Callback) {
return ReflectUtils.getClasses(getCallbacks());
} else {
return (Class[])callbacks.toArray(new Class[callbacks.size()]);
}
}
public int accept(Method method)
{
return ((Integer)methodMap.get(method)).intValue();
}
public int hashCode()
{
return methodMap.hashCode();
}
public boolean equals(Object o)
{
if (o == null)
return false;
if (!(o instanceof CallbackHelper))
return false;
return methodMap.equals(((CallbackHelper)o).methodMap);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/reflect/ 0000755 0001750 0001750 00000000000 12250627450 020642 5 ustar miguel miguel cglib3-3.1+dfsg/src/proxy/net/sf/cglib/reflect/ConstructorDelegate.java 0000644 0001750 0001750 00000010552 10402432050 025453 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.reflect;
import java.lang.reflect.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
/**
* @author Chris Nokleberg
* @version $Id: ConstructorDelegate.java,v 1.20 2006/03/05 02:43:19 herbyderby Exp $
*/
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);
}
protected ConstructorDelegate() {
}
public static ConstructorDelegate create(Class targetClass, Class iface) {
Generator gen = new Generator();
gen.setTargetClass(targetClass);
gen.setInterface(iface);
return gen.create();
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(ConstructorDelegate.class.getName());
private static final Type CONSTRUCTOR_DELEGATE =
TypeUtils.parseType("net.sf.cglib.reflect.ConstructorDelegate");
private Class iface;
private Class targetClass;
public Generator() {
super(SOURCE);
}
public void setInterface(Class iface) {
this.iface = iface;
}
public void setTargetClass(Class targetClass) {
this.targetClass = targetClass;
}
public ConstructorDelegate create() {
setNamePrefix(targetClass.getName());
Object key = KEY_FACTORY.newInstance(iface.getName(), targetClass.getName());
return (ConstructorDelegate)super.create(key);
}
protected ClassLoader getDefaultClassLoader() {
return targetClass.getClassLoader();
}
public void generateClass(ClassVisitor v) {
setNamePrefix(targetClass.getName());
final Method newInstance = ReflectUtils.findNewInstance(iface);
if (!newInstance.getReturnType().isAssignableFrom(targetClass)) {
throw new IllegalArgumentException("incompatible return type");
}
final Constructor constructor;
try {
constructor = targetClass.getDeclaredConstructor(newInstance.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("interface does not match any known constructor");
}
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
CONSTRUCTOR_DELEGATE,
new Type[]{ Type.getType(iface) },
Constants.SOURCE_FILE);
Type declaring = Type.getType(constructor.getDeclaringClass());
EmitUtils.null_constructor(ce);
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
ReflectUtils.getSignature(newInstance),
ReflectUtils.getExceptionTypes(newInstance));
e.new_instance(declaring);
e.dup();
e.load_args();
e.invoke_constructor(declaring, ReflectUtils.getSignature(constructor));
e.return_value();
e.end_method();
ce.end_class();
}
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type);
}
protected Object nextInstance(Object instance) {
return instance;
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/reflect/FastClassEmitter.java 0000644 0001750 0001750 00000022510 10402432050 024705 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.reflect;
import java.lang.reflect.*;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
class FastClassEmitter extends ClassEmitter {
private static final Signature CSTRUCT_CLASS =
TypeUtils.parseConstructor("Class");
private static final Signature METHOD_GET_INDEX =
TypeUtils.parseSignature("int getIndex(String, Class[])");
private static final Signature SIGNATURE_GET_INDEX =
new Signature("getIndex", Type.INT_TYPE, new Type[]{ Constants.TYPE_SIGNATURE });
private static final Signature TO_STRING =
TypeUtils.parseSignature("String toString()");
private static final Signature CONSTRUCTOR_GET_INDEX =
TypeUtils.parseSignature("int getIndex(Class[])");
private static final Signature INVOKE =
TypeUtils.parseSignature("Object invoke(int, Object, Object[])");
private static final Signature NEW_INSTANCE =
TypeUtils.parseSignature("Object newInstance(int, Object[])");
private static final Signature GET_MAX_INDEX =
TypeUtils.parseSignature("int getMaxIndex()");
private static final Signature GET_SIGNATURE_WITHOUT_RETURN_TYPE =
TypeUtils.parseSignature("String getSignatureWithoutReturnType(String, Class[])");
private static final Type FAST_CLASS =
TypeUtils.parseType("net.sf.cglib.reflect.FastClass");
private static final Type ILLEGAL_ARGUMENT_EXCEPTION =
TypeUtils.parseType("IllegalArgumentException");
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);
Type base = Type.getType(type);
begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, FAST_CLASS, null, Constants.SOURCE_FILE);
// constructor
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_CLASS, null);
e.load_this();
e.load_args();
e.super_invoke_constructor(CSTRUCT_CLASS);
e.return_value();
e.end_method();
VisibilityPredicate vp = new VisibilityPredicate(type, false);
List methods = ReflectUtils.addAllMethods(type, new ArrayList());
CollectionUtils.filter(methods, vp);
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();
List info = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
EmitUtils.constructor_switch(e, info, new GetIndexCallback(e, info));
e.end_method();
// invoke(int, Object, Object[])
e = begin_method(Constants.ACC_PUBLIC, INVOKE, INVOCATION_TARGET_EXCEPTION_ARRAY);
e.load_arg(1);
e.checkcast(base);
e.load_arg(0);
invokeSwitchHelper(e, methods, 2, base);
e.end_method();
// newInstance(int, Object[])
e = begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, INVOCATION_TARGET_EXCEPTION_ARRAY);
e.new_instance(base);
e.dup();
e.load_arg(0);
invokeSwitchHelper(e, constructors, 1, base);
e.end_method();
// getMaxIndex()
e = begin_method(Constants.ACC_PUBLIC, GET_MAX_INDEX, null);
e.push(methods.size() - 1);
e.return_value();
e.end_method();
end_class();
}
// TODO: support constructor indices ("-1
if none is found.
*/
abstract public int getIndex(String name, Class[] parameterTypes);
/**
* Return the index of the matching constructor. The index may be used
* later to create a new instance with less overhead.
* @see #newInstance(int, Object[])
* @param parameterTypes the parameter array
* @return the constructor index, or -1
if none is found.
*/
abstract public int getIndex(Class[] parameterTypes);
/**
* Invoke the method with the specified index.
* @see getIndex(name, Class[])
* @param index the method index
* @param obj the object the underlying method is invoked from
* @param args the arguments used for the method call
* @throws java.lang.reflect.InvocationTargetException if the underlying method throws an exception
*/
abstract public Object invoke(int index, Object obj, Object[] args) throws InvocationTargetException;
/**
* Create a new instance using the specified constructor index and arguments.
* @see getIndex(Class[])
* @param index the constructor index
* @param args the arguments passed to the constructor
* @throws java.lang.reflect.InvocationTargetException if the constructor throws an exception
*/
abstract public Object newInstance(int index, Object[] args) throws InvocationTargetException;
abstract public int getIndex(Signature sig);
/**
* Returns the maximum method index for this class.
*/
abstract public int getMaxIndex();
protected static String getSignatureWithoutReturnType(String name, Class[] parameterTypes) {
StringBuffer sb = new StringBuffer();
sb.append(name);
sb.append('(');
for (int i = 0; i < parameterTypes.length; i++) {
sb.append(Type.getDescriptor(parameterTypes[i]));
}
sb.append(')');
return sb.toString();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/reflect/MethodDelegate.java 0000644 0001750 0001750 00000023426 10402432050 024352 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.reflect;
import java.lang.reflect.*;
import net.sf.cglib.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
// TODO: don't require exact match for return type
/**
* DOCUMENTATION FROM APACHE AVALON DELEGATE CLASS
*
* Delegate
*
* public interface MainDelegate {
* int main(String[] args);
* }
*
*
* MethodDelegate.create(this, "alternateMain", MainDelegate.class)
.
* The following program will show how to use it:
*
* public class Main {
* public static int main( String[] args ) {
* Main newMain = new Main();
* MainDelegate start = (MainDelegate)
* MethodDelegate.create(newMain, "alternateMain", MainDelegate.class);
* return start.main( args );
* }
*
* public int alternateMain( String[] args ) {
* for (int i = 0; i < args.length; i++) {
* System.out.println( args[i] );
* }
* return args.length;
* }
* }
*
*
* main
method by
* substituting the delegate creation call with this:
* MethodDelegate.createStatic(getClass(), "main", MainDelegate.class)
.
* Equality
* The criteria that we use to test if two delegates are equal are:
*
*
*
* @version $Id: MethodDelegate.java,v 1.25 2006/03/05 02:43:19 herbyderby Exp $
*/
abstract public class MethodDelegate {
private static final MethodDelegateKey KEY_FACTORY =
(MethodDelegateKey)KeyFactory.create(MethodDelegateKey.class, KeyFactory.CLASS_BY_NAME);
protected Object target;
protected String eqMethod;
interface MethodDelegateKey {
Object newInstance(Class delegateClass, String methodName, Class iface);
}
public static MethodDelegate createStatic(Class targetClass, String methodName, Class iface) {
Generator gen = new Generator();
gen.setTargetClass(targetClass);
gen.setMethodName(methodName);
gen.setInterface(iface);
return gen.create();
}
public static MethodDelegate create(Object target, String methodName, Class iface) {
Generator gen = new Generator();
gen.setTarget(target);
gen.setMethodName(methodName);
gen.setInterface(iface);
return gen.create();
}
public boolean equals(Object obj) {
MethodDelegate other = (MethodDelegate)obj;
return target == other.target && eqMethod.equals(other.eqMethod);
}
public int hashCode() {
return target.hashCode() ^ eqMethod.hashCode();
}
public Object getTarget() {
return target;
}
abstract public MethodDelegate newInstance(Object target);
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(MethodDelegate.class.getName());
private static final Type METHOD_DELEGATE =
TypeUtils.parseType("net.sf.cglib.reflect.MethodDelegate");
private static final Signature NEW_INSTANCE =
new Signature("newInstance", METHOD_DELEGATE, new Type[]{ Constants.TYPE_OBJECT });
private Object target;
private Class targetClass;
private String methodName;
private Class iface;
public Generator() {
super(SOURCE);
}
public void setTarget(Object target) {
this.target = target;
this.targetClass = target.getClass();
}
public void setTargetClass(Class targetClass) {
this.targetClass = targetClass;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public void setInterface(Class iface) {
this.iface = iface;
}
protected ClassLoader getDefaultClassLoader() {
return targetClass.getClassLoader();
}
public MethodDelegate create() {
setNamePrefix(targetClass.getName());
Object key = KEY_FACTORY.newInstance(targetClass, methodName, iface);
return (MethodDelegate)super.create(key);
}
protected Object firstInstance(Class type) {
return ((MethodDelegate)ReflectUtils.newInstance(type)).newInstance(target);
}
protected Object nextInstance(Object instance) {
return ((MethodDelegate)instance).newInstance(target);
}
public void generateClass(ClassVisitor v) throws NoSuchMethodException {
Method proxy = ReflectUtils.findInterfaceMethod(iface);
final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes());
if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) {
throw new IllegalArgumentException("incompatible return types");
}
MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);
boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers());
if ((target == null) ^ isStatic) {
throw new IllegalArgumentException("Static method " + (isStatic ? "not " : "") + "expected");
}
ClassEmitter ce = new ClassEmitter(v);
CodeEmitter e;
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
METHOD_DELEGATE,
new Type[]{ Type.getType(iface) },
Constants.SOURCE_FILE);
ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null);
EmitUtils.null_constructor(ce);
// generate proxied method
MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]);
e = EmitUtils.begin_method(ce, proxied, Constants.ACC_PUBLIC);
e.load_this();
e.super_getfield("target", Constants.TYPE_OBJECT);
e.checkcast(methodInfo.getClassInfo().getType());
e.load_args();
e.invoke(methodInfo);
e.return_value();
e.end_method();
// newInstance
e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
e.new_instance_this();
e.dup();
e.dup2();
e.invoke_constructor_this();
e.getfield("eqMethod");
e.super_putfield("eqMethod", Constants.TYPE_STRING);
e.load_arg(0);
e.super_putfield("target", Constants.TYPE_OBJECT);
e.return_value();
e.end_method();
// static initializer
e = ce.begin_static();
e.push(methodInfo.getSignature().toString());
e.putfield("eqMethod");
e.return_value();
e.end_method();
ce.end_class();
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ 0000755 0001750 0001750 00000000000 12250627450 021231 5 ustar miguel miguel cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassFilter.java 0000644 0001750 0001750 00000001426 10066633126 024312 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
/**
*
* @author baliuka
*/
public interface ClassFilter {
boolean accept(String className);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/AbstractClassFilterTransformer.java 0000644 0001750 0001750 00000006100 10402432046 030203 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.*;
abstract public class AbstractClassFilterTransformer extends AbstractClassTransformer {
private ClassTransformer pass;
private ClassVisitor target;
public void setTarget(ClassVisitor target) {
super.setTarget(target);
pass.setTarget(target);
}
protected AbstractClassFilterTransformer(ClassTransformer pass) {
this.pass = pass;
}
abstract protected boolean accept(int version, int access, String name, String signature, String superName, String[] interfaces);
public void visit(int version,
int access,
String name,
String signature,
String superName,
String[] interfaces) {
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) {
target.visitSource(source, debug);
}
public void visitOuterClass(String owner, String name, String desc) {
target.visitOuterClass(owner, name, desc);
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return target.visitAnnotation(desc, visible);
}
public void visitAttribute(Attribute attr) {
target.visitAttribute(attr);
}
public void visitInnerClass(String name, String outerName, String innerName, int access) {
target.visitInnerClass(name, outerName, innerName, access);
}
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,
String name,
String desc,
String signature,
String[] exceptions) {
return target.visitMethod(access, name, desc, signature, exceptions);
}
public void visitEnd() {
target.visitEnd();
target = null; // just to be safe
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/AbstractProcessTask.java 0000644 0001750 0001750 00000004247 10211265442 026022 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import java.io.File;
import java.util.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
abstract public class AbstractProcessTask extends Task {
private Vector filesets = new Vector();
public void addFileset(FileSet set) {
filesets.addElement(set);
}
protected Collection getFiles() {
Map fileMap = new HashMap();
Project p = getProject();
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet)filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(p);
String[] srcFiles = ds.getIncludedFiles();
File dir = fs.getDir(p);
for (int j = 0; j < srcFiles.length; j++) {
File src = new File(dir, srcFiles[j]);
fileMap.put(src.getAbsolutePath(), src);
}
}
return fileMap.values();
}
public void execute() throws BuildException {
beforeExecute();
for (Iterator it = getFiles().iterator(); it.hasNext();) {
try {
processFile((File)it.next());
} catch (Exception e) {
throw new BuildException(e);
}
}
}
protected void beforeExecute() throws BuildException { }
abstract protected void processFile(File file) throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassReaderGenerator.java 0000644 0001750 0001750 00000002573 11016424462 026137 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.ClassGenerator;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
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);
}
public ClassReaderGenerator(ClassReader r, Attribute[] attrs, int flags) {
this.r = r;
this.attrs = (attrs != null) ? attrs : new Attribute[0];
this.flags = flags;
}
public void generateClass(ClassVisitor v) {
r.accept(v, attrs, flags);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/AnnotationVisitorTee.java 0000644 0001750 0001750 00000003743 12250620400 026217 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
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;
return new AnnotationVisitorTee(av1, av2);
}
public AnnotationVisitorTee(AnnotationVisitor av1, AnnotationVisitor av2) {
super(Opcodes.ASM4);
this.av1 = av1;
this.av2 = av2;
}
public void visit(String name, Object value) {
av2.visit(name, value);
av2.visit(name, value);
}
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) {
return getInstance(av1.visitAnnotation(name, desc),
av2.visitAnnotation(name, desc));
}
public AnnotationVisitor visitArray(String name) {
return getInstance(av1.visitArray(name), av2.visitArray(name));
}
public void visitEnd() {
av1.visitEnd();
av2.visitEnd();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/AbstractClassTransformer.java 0000644 0001750 0001750 00000001730 12250620400 027035 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
abstract public class AbstractClassTransformer extends ClassTransformer {
protected AbstractClassTransformer() {
super(Opcodes.ASM4);
}
public void setTarget(ClassVisitor target) {
cv = target;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassVisitorTee.java 0000644 0001750 0001750 00000007013 12250620400 025144 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.*;
public class ClassVisitorTee extends ClassVisitor {
private ClassVisitor cv1, cv2;
public ClassVisitorTee(ClassVisitor cv1, ClassVisitor cv2) {
super(Opcodes.ASM4);
this.cv1 = cv1;
this.cv2 = cv2;
}
public void visit(int version,
int access,
String name,
String signature,
String superName,
String[] interfaces) {
cv1.visit(version, access, name, signature, superName, interfaces);
cv2.visit(version, access, name, signature, superName, interfaces);
}
public void visitEnd() {
cv1.visitEnd();
cv2.visitEnd();
cv1 = cv2 = null;
}
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,
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;
return new FieldVisitorTee(fv1, fv2);
}
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;
return new MethodVisitorTee(mv1, mv2);
}
public void visitSource(String source, String debug) {
cv1.visitSource(source, debug);
cv2.visitSource(source, debug);
}
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) {
return AnnotationVisitorTee.getInstance(cv1.visitAnnotation(desc, visible),
cv2.visitAnnotation(desc, visible));
}
public void visitAttribute(Attribute attrs) {
cv1.visitAttribute(attrs);
cv2.visitAttribute(attrs);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassTransformer.java 0000644 0001750 0001750 00000001745 12250620400 025357 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
public abstract class ClassTransformer extends ClassVisitor {
public ClassTransformer() {
super(Opcodes.ASM4);
}
public ClassTransformer(int opcode) {
super(opcode);
}
public abstract void setTarget(ClassVisitor target);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/MethodFilter.java 0000644 0001750 0001750 00000001553 10402432046 024456 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.Attribute;
public interface MethodFilter {
// TODO: pass class name too?
boolean accept(int access, String name, String desc, String signature, String[] exceptions);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassTransformerFactory.java 0000644 0001750 0001750 00000001357 10066633126 026722 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
public interface ClassTransformerFactory {
ClassTransformer newInstance();
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/FieldVisitorTee.java 0000644 0001750 0001750 00000003011 12250620400 025114 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
public class FieldVisitorTee extends FieldVisitor {
private FieldVisitor fv1, fv2;
public FieldVisitorTee(FieldVisitor fv1, FieldVisitor fv2) {
super(Opcodes.ASM4);
this.fv1 = fv1;
this.fv2 = fv2;
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(fv1.visitAnnotation(desc, visible),
fv2.visitAnnotation(desc, visible));
}
public void visitAttribute(Attribute attr) {
fv1.visitAttribute(attr);
fv2.visitAttribute(attr);
}
public void visitEnd() {
fv1.visitEnd();
fv2.visitEnd();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassEmitterTransformer.java 0000644 0001750 0001750 00000001416 12250620400 026704 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.ClassEmitter;
abstract public class ClassEmitterTransformer extends ClassEmitter {
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassFilterTransformer.java 0000644 0001750 0001750 00000002176 10402432046 026530 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.*;
public class ClassFilterTransformer extends AbstractClassFilterTransformer {
private ClassFilter filter;
public ClassFilterTransformer(ClassFilter filter, ClassTransformer pass) {
super(pass);
this.filter = filter;
}
protected boolean accept(int version, int access, String name, String signature, String superName, String[] interfaces) {
return filter.accept(name.replace('/', '.'));
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/AbstractClassLoader.java 0000644 0001750 0001750 00000007136 12250620400 025747 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.CodeGenerationException;
import net.sf.cglib.core.ClassGenerator;
import net.sf.cglib.core.DebuggingClassWriter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.util.*;
import org.objectweb.asm.Attribute;
import java.io.IOException;
abstract public class AbstractClassLoader extends ClassLoader {
private ClassFilter filter;
private ClassLoader classPath;
private static java.security.ProtectionDomain DOMAIN ;
static{
DOMAIN = (java.security.ProtectionDomain)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
return 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 {
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(
name.replace('.','/') + ".class"
);
if (is == null) {
throw new ClassNotFoundException(name);
}
try {
r = new ClassReader(is);
} finally {
is.close();
}
} catch (IOException e) {
throw new ClassNotFoundException(name + ":" + e.getMessage());
}
try {
DebuggingClassWriter w =
new DebuggingClassWriter(ClassWriter.COMPUTE_MAXS);
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) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
protected ClassGenerator getGenerator(ClassReader r) {
return new ClassReaderGenerator(r, attributes(), getFlags());
}
protected int getFlags() {
return 0;
}
protected Attribute[] attributes() {
return null;
}
protected void postProcess(Class c) {
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassTransformerChain.java 0000644 0001750 0001750 00000003611 10402432046 026320 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.*;
public class ClassTransformerChain extends AbstractClassTransformer {
private ClassTransformer[] chain;
public ClassTransformerChain(ClassTransformer[] chain) {
this.chain = (ClassTransformer[])chain.clone();
}
public void setTarget(ClassVisitor v) {
super.setTarget(chain[0]);
ClassVisitor next = v;
for (int i = chain.length - 1; i >= 0; i--) {
chain[i].setTarget(next);
next = chain[i];
}
}
public MethodVisitor visitMethod(int access,
String name,
String desc,
String signature,
String[] exceptions) {
return cv.visitMethod(access, name, desc, signature, exceptions);
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("ClassTransformerChain{");
for (int i = 0; i < chain.length; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(chain[i].toString());
}
sb.append("}");
return sb.toString();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/TransformingClassGenerator.java 0000644 0001750 0001750 00000002263 10066633126 027405 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import net.sf.cglib.core.ClassGenerator;
import net.sf.cglib.core.Transformer;
import org.objectweb.asm.ClassVisitor;
public class TransformingClassGenerator implements ClassGenerator {
private ClassGenerator gen;
private ClassTransformer t;
public TransformingClassGenerator(ClassGenerator gen, ClassTransformer t) {
this.gen = gen;
this.t = t;
}
public void generateClass(ClassVisitor v) throws Exception {
t.setTarget(v);
gen.generateClass(t);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/MethodFilterTransformer.java 0000644 0001750 0001750 00000003112 10402432046 026672 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.*;
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,
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) {
pass.setTarget(target);
direct = target;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/ClassTransformerTee.java 0000644 0001750 0001750 00000002076 12250620400 026013 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
public class ClassTransformerTee extends ClassTransformer {
private ClassVisitor branch;
public ClassTransformerTee(ClassVisitor branch) {
super(Opcodes.ASM4);
this.branch = branch;
}
public void setTarget(ClassVisitor target) {
cv = new ClassVisitorTee(branch, target);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/AbstractTransformTask.java 0000644 0001750 0001750 00000021223 12250620400 026342 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package net.sf.cglib.transform;
import java.io.*;
import java.net.MalformedURLException;
import java.util.*;
import java.util.zip.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.sf.cglib.core.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ProjectComponent;
import org.objectweb.asm.*;
abstract public class AbstractTransformTask extends AbstractProcessTask {
private static final int ZIP_MAGIC = 0x504B0304;
private static final int CLASS_MAGIC = 0xCAFEBABE;
private boolean verbose;
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
/**
* returns transformation for source class
*
* @param classInfo
* class information
* class name := classInfo[ 0 ]
* super class name := classInfo[ 1 ]
* interfaces := classInfo[ >1 ]
*/
abstract protected ClassTransformer getClassTransformer(String[] classInfo);
protected Attribute[] attributes() {
return null;
}
protected void processFile(File file) throws Exception {
if (isClassFile(file)) {
processClassFile(file);
} else if (isJarFile(file)) {
processJarFile(file);
} else {
log("ignoring " + file.toURI(), Project.MSG_WARN);
}
}
/**
* @param file
* @throws Exception
* @throws FileNotFoundException
* @throws IOException
* @throws MalformedURLException
*/
private void processClassFile(File file) throws Exception,
FileNotFoundException, IOException, MalformedURLException {
ClassReader reader = getClassReader(file);
String name[] = ClassNameReader.getClassInfo(reader);
DebuggingClassWriter w =
new DebuggingClassWriter(ClassWriter.COMPUTE_MAXS);
ClassTransformer t = getClassTransformer(name);
if (t != null) {
if (verbose) {
log("processing " + file.toURI());
}
new TransformingClassGenerator(new ClassReaderGenerator(
getClassReader(file), attributes(), getFlags()), t)
.generateClass(w);
FileOutputStream fos = new FileOutputStream(file);
try {
fos.write(w.toByteArray());
} finally {
fos.close();
}
}
}
protected int getFlags() {
return 0;
}
private static ClassReader getClassReader(File file) throws Exception {
InputStream in = new BufferedInputStream(new FileInputStream(file));
try {
ClassReader r = new ClassReader(in);
return r;
} finally {
in.close();
}
}
protected boolean isClassFile(File file) throws IOException {
return checkMagic(file, CLASS_MAGIC);
}
protected void processJarFile(File file) throws Exception {
if (verbose) {
log("processing " + file.toURI());
}
File tempFile = File.createTempFile(file.getName(), null, new File(file
.getAbsoluteFile().getParent()));
try{
ZipInputStream zip = new ZipInputStream(new FileInputStream(file));
try {
FileOutputStream fout = new FileOutputStream(tempFile);
try{
ZipOutputStream out = new ZipOutputStream(fout);
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
byte bytes[] = getBytes(zip);
if (!entry.isDirectory()) {
DataInputStream din = new DataInputStream(
new ByteArrayInputStream(bytes)
);
if (din.readInt() == CLASS_MAGIC) {
bytes = process(bytes);
} else {
if (verbose) {
log("ignoring " + entry.toString());
}
}
}
ZipEntry outEntry = new ZipEntry(entry.getName());
outEntry.setMethod(entry.getMethod());
outEntry.setComment(entry.getComment());
outEntry.setSize(bytes.length);
if(outEntry.getMethod() == ZipEntry.STORED){
CRC32 crc = new CRC32();
crc.update(bytes);
outEntry.setCrc( crc.getValue() );
outEntry.setCompressedSize(bytes.length);
}
out.putNextEntry(outEntry);
out.write(bytes);
out.closeEntry();
zip.closeEntry();
}
out.close();
}finally{
fout.close();
}
} finally {
zip.close();
}
if(file.delete()){
File newFile = new File(tempFile.getAbsolutePath());
if(!newFile.renameTo(file)){
throw new IOException("can not rename " + tempFile + " to " + file);
}
}else{
throw new IOException("can not delete " + file);
}
}finally{
tempFile.delete();
}
}
/**
* @param bytes
* @return
* @throws IOException
* @throws Exception
*/
private byte[] process(byte[] bytes) throws Exception {
ClassReader reader = new ClassReader(new ByteArrayInputStream(bytes));
String name[] = ClassNameReader.getClassInfo(reader);
DebuggingClassWriter w =
new DebuggingClassWriter(ClassWriter.COMPUTE_MAXS);
ClassTransformer t = getClassTransformer(name);
if (t != null) {
if (verbose) {
log("processing " + name[0]);
}
new TransformingClassGenerator(new ClassReaderGenerator(
new ClassReader(new ByteArrayInputStream(bytes)),
attributes(), getFlags()), t).generateClass(w);
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(w.toByteArray());
return out.toByteArray();
}
return bytes;
}
/**
* @param zip
* @return
* @throws IOException
*/
private byte[] getBytes(ZipInputStream zip) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
InputStream in = new BufferedInputStream(zip);
int b;
while ((b = in.read()) != -1) {
bout.write(b);
}
return bout.toByteArray();
}
private boolean checkMagic(File file, long magic) throws IOException {
DataInputStream in = new DataInputStream(new FileInputStream(file));
try {
int m = in.readInt();
return magic == m;
} finally {
in.close();
}
}
protected boolean isJarFile(File file) throws IOException {
return checkMagic(file, ZIP_MAGIC);
}
} cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/ 0000755 0001750 0001750 00000000000 12250627450 022172 5 ustar miguel miguel cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/AddStaticInitTransformer.java 0000644 0001750 0001750 00000003362 10066633126 027750 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import java.lang.reflect.Method;
import net.sf.cglib.core.*;
import net.sf.cglib.transform.*;
import org.objectweb.asm.Type;
/**
* @author Juozas Baliuka, Chris Nokleberg
*/
public class AddStaticInitTransformer extends ClassEmitterTransformer {
private MethodInfo info;
public AddStaticInitTransformer(Method classInit) {
info = ReflectUtils.getMethodInfo(classInit);
if (!TypeUtils.isStatic(info.getModifiers())) {
throw new IllegalArgumentException(classInit + " is not static");
}
Type[] types = info.getSignature().getArgumentTypes();
if (types.length != 1 ||
!types[0].equals(Constants.TYPE_CLASS) ||
!info.getSignature().getReturnType().equals(Type.VOID_TYPE)) {
throw new IllegalArgumentException(classInit + " illegal signature");
}
}
protected void init() {
if (!TypeUtils.isInterface(getAccess())) {
CodeEmitter e = getStaticHook();
EmitUtils.load_class_this(e);
e.invoke(info);
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/FieldProvider.java 0000644 0001750 0001750 00000001731 10066633126 025575 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
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);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/AccessFieldTransformer.java 0000644 0001750 0001750 00000004441 10402432046 027420 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import net.sf.cglib.transform.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Type;
public class AccessFieldTransformer extends ClassEmitterTransformer {
private Callback callback;
public AccessFieldTransformer(Callback callback) {
this.callback = callback;
}
public interface Callback {
String getPropertyName(Type owner, String fieldName);
}
public void declare_field(int access, final String name, Type type, Object value) {
super.declare_field(access, name, type, value);
String property = TypeUtils.upperFirst(callback.getPropertyName(getClassType(), name));
if (property != null) {
CodeEmitter e;
e = begin_method(Constants.ACC_PUBLIC,
new Signature("get" + property,
type,
Constants.TYPES_EMPTY),
null);
e.load_this();
e.getfield(name);
e.return_value();
e.end_method();
e = begin_method(Constants.ACC_PUBLIC,
new Signature("set" + property,
Type.VOID_TYPE,
new Type[]{ type }),
null);
e.load_this();
e.load_arg(0);
e.putfield(name);
e.return_value();
e.end_method();
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/AbstractInterceptFieldCallback.java 0000644 0001750 0001750 00000005010 10066633126 031033 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.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; }
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/AddInitTransformer.java 0000644 0001750 0001750 00000004251 10402432046 026566 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import java.lang.reflect.Method;
import net.sf.cglib.core.CodeEmitter;
import net.sf.cglib.core.Constants;
import net.sf.cglib.core.MethodInfo;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.transform.ClassEmitterTransformer;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Type;
/**
* @author Mark Hobson
*/
public class AddInitTransformer extends ClassEmitterTransformer {
private MethodInfo info;
public AddInitTransformer(Method method) {
info = ReflectUtils.getMethodInfo(method);
Type[] types = info.getSignature().getArgumentTypes();
if (types.length != 1 ||
!types[0].equals(Constants.TYPE_OBJECT) ||
!info.getSignature().getReturnType().equals(Type.VOID_TYPE)) {
throw new IllegalArgumentException(method + " illegal signature");
}
}
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
final CodeEmitter emitter = super.begin_method(access, sig, exceptions);
if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) {
return new CodeEmitter(emitter) {
public void visitInsn(int opcode) {
if (opcode == Constants.RETURN) {
load_this();
invoke(info);
}
super.visitInsn(opcode);
}
};
}
return emitter;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/AddPropertyTransformer.java 0000644 0001750 0001750 00000003020 10066633126 027510 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import net.sf.cglib.transform.*;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Type;
public class AddPropertyTransformer extends ClassEmitterTransformer {
private final String[] names;
private final Type[] types;
public AddPropertyTransformer(Map props) {
int size = props.size();
names = (String[])props.keySet().toArray(new String[size]);
types = new Type[size];
for (int i = 0; i < size; i++) {
types[i] = (Type)props.get(names[i]);
}
}
public AddPropertyTransformer(String[] names, Type[] types) {
this.names = names;
this.types = types;
}
public void end_class() {
if (!TypeUtils.isAbstract(getAccess())) {
EmitUtils.add_properties(this, names, types);
}
super.end_class();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/InterceptFieldCallback.java 0000644 0001750 0001750 00000003773 10066633126 027365 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.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);
boolean writeBoolean(Object obj, String name, boolean oldValue, boolean newValue);
short writeShort(Object obj, String name, short oldValue, short newValue);
float writeFloat(Object obj, String name, float oldValue, float newValue);
double writeDouble(Object obj, String name, double oldValue, double newValue);
long writeLong(Object obj, String name, long oldValue, long newValue);
Object writeObject(Object obj, String name, Object oldValue, Object newValue);
int readInt(Object obj, String name, int oldValue);
char readChar(Object obj, String name, char oldValue);
byte readByte(Object obj, String name, byte oldValue);
boolean readBoolean(Object obj, String name, boolean oldValue);
short readShort(Object obj, String name, short oldValue);
float readFloat(Object obj, String name, float oldValue);
double readDouble(Object obj, String name, double oldValue);
long readLong(Object obj, String name, long oldValue);
Object readObject(Object obj, String name, Object oldValue);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/InterceptFieldFilter.java 0000644 0001750 0001750 00000001523 10066633126 027105 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import org.objectweb.asm.Type;
public interface InterceptFieldFilter {
boolean acceptRead(Type owner, String name);
boolean acceptWrite(Type owner, String name);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/InterceptFieldEnabled.java 0000644 0001750 0001750 00000001514 10066633126 027212 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
public interface InterceptFieldEnabled {
void setInterceptFieldCallback(InterceptFieldCallback callback);
InterceptFieldCallback getInterceptFieldCallback();
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/FieldProviderTransformer.java 0000644 0001750 0001750 00000020177 10402432046 030015 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import net.sf.cglib.transform.*;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
public class FieldProviderTransformer extends ClassEmitterTransformer {
private static final String FIELD_NAMES = "CGLIB$FIELD_NAMES";
private static final String FIELD_TYPES = "CGLIB$FIELD_TYPES";
private static final Type FIELD_PROVIDER =
TypeUtils.parseType("net.sf.cglib.transform.impl.FieldProvider");
private static final Type ILLEGAL_ARGUMENT_EXCEPTION =
TypeUtils.parseType("IllegalArgumentException");
private static final Signature PROVIDER_GET =
TypeUtils.parseSignature("Object getField(String)");
private static final Signature PROVIDER_SET =
TypeUtils.parseSignature("void setField(String, Object)");
private static final Signature PROVIDER_SET_BY_INDEX =
TypeUtils.parseSignature("void setField(int, Object)");
private static final Signature PROVIDER_GET_BY_INDEX =
TypeUtils.parseSignature("Object getField(int)");
private static final Signature PROVIDER_GET_TYPES =
TypeUtils.parseSignature("Class[] getFieldTypes()");
private static final Signature PROVIDER_GET_NAMES =
TypeUtils.parseSignature("String[] getFieldNames()");
private int access;
private Map fields;
public void begin_class(int version, int access, String className, Type superType, Type[] interfaces, String sourceFile) {
if (!TypeUtils.isAbstract(access)) {
interfaces = TypeUtils.add(interfaces, FIELD_PROVIDER);
}
this.access = access;
fields = new HashMap();
super.begin_class(version, access, className, superType, interfaces, sourceFile);
}
public void declare_field(int access, String name, Type type, Object value) {
super.declare_field(access, name, type, value);
if (!TypeUtils.isStatic(access)) {
fields.put(name, type);
}
}
public void end_class() {
if (!TypeUtils.isInterface(access)) {
try {
generate();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
super.end_class();
}
private void generate() throws Exception {
final String[] names = (String[])fields.keySet().toArray(new String[fields.size()]);
int indexes[] = new int[names.length];
for (int i = 0; i < indexes.length; i++) {
indexes[i] = i;
}
super.declare_field(Constants.PRIVATE_FINAL_STATIC, FIELD_NAMES, Constants.TYPE_STRING_ARRAY, null);
super.declare_field(Constants.PRIVATE_FINAL_STATIC, FIELD_TYPES, Constants.TYPE_CLASS_ARRAY, null);
// use separate methods here because each process switch inner class needs a final CodeEmitter
initFieldProvider(names);
getNames();
getTypes();
getField(names);
setField(names);
setByIndex(names, indexes);
getByIndex(names, indexes);
}
private void initFieldProvider(String[] names) {
CodeEmitter e = getStaticHook();
EmitUtils.push_object(e, names);
e.putstatic(getClassType(), FIELD_NAMES, Constants.TYPE_STRING_ARRAY);
e.push(names.length);
e.newarray(Constants.TYPE_CLASS);
e.dup();
for(int i = 0; i < names.length; i++ ){
e.dup();
e.push(i);
Type type = (Type)fields.get(names[i]);
EmitUtils.load_class(e, type);
e.aastore();
}
e.putstatic(getClassType(), FIELD_TYPES, Constants.TYPE_CLASS_ARRAY);
}
private void getNames() {
CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_NAMES, null);
e.getstatic(getClassType(), FIELD_NAMES, Constants.TYPE_STRING_ARRAY);
e.return_value();
e.end_method();
}
private void getTypes() {
CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_TYPES, null);
e.getstatic(getClassType(), FIELD_TYPES, Constants.TYPE_CLASS_ARRAY);
e.return_value();
e.end_method();
}
private void setByIndex(final String[] names, final int[] indexes) throws Exception {
final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_SET_BY_INDEX, null);
e.load_this();
e.load_arg(1);
e.load_arg(0);
e.process_switch(indexes, new ProcessSwitchCallback() {
public void processCase(int key, Label end) throws Exception {
Type type = (Type)fields.get(names[key]);
e.unbox(type);
e.putfield(names[key]);
e.return_value();
}
public void processDefault() throws Exception {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index");
}
});
e.end_method();
}
private void getByIndex(final String[] names, final int[] indexes) throws Exception {
final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_BY_INDEX, null);
e.load_this();
e.load_arg(0);
e.process_switch(indexes, new ProcessSwitchCallback() {
public void processCase(int key, Label end) throws Exception {
Type type = (Type)fields.get(names[key]);
e.getfield(names[key]);
e.box(type);
e.return_value();
}
public void processDefault() throws Exception {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index");
}
});
e.end_method();
}
// TODO: if this is used to enhance class files SWITCH_STYLE_TRIE should be used
// to avoid JVM hashcode implementation incompatibilities
private void getField(String[] names) throws Exception {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_GET, null);
e.load_this();
e.load_arg(0);
EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
Type type = (Type)fields.get(key);
e.getfield((String)key);
e.box(type);
e.return_value();
}
public void processDefault() {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name");
}
});
e.end_method();
}
private void setField(String[] names) throws Exception {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_SET, null);
e.load_this();
e.load_arg(1);
e.load_arg(0);
EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) {
Type type = (Type)fields.get(key);
e.unbox(type);
e.putfield((String)key);
e.return_value();
}
public void processDefault() {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name");
}
});
e.end_method();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/AddDelegateTransformer.java 0000644 0001750 0001750 00000011023 10402432046 027370 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import net.sf.cglib.transform.*;
import java.lang.reflect.*;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Type;
/**
* @author Juozas Baliuka
*/
public class AddDelegateTransformer extends ClassEmitterTransformer {
private static final String DELEGATE = "$CGLIB_DELEGATE";
private static final Signature CSTRUCT_OBJECT =
TypeUtils.parseSignature("void instance
* parameter passed to the newDelegate method was the same for both. The
* instances are compared with the identity equality operator, ==
.
* Method.equals
.Throwable
and which has at least one
* constructor that takes a single argument of type
* Throwable
, for example
* java.lang.reflect.UndeclaredThrowableException.class
*/
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 {
ClassTransformer tr = new UndeclaredThrowableTransformer(wrapper);
tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
return new TransformingClassGenerator(cg, tr);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/UndeclaredThrowableTransformer.java 0000644 0001750 0001750 00000004440 10402432046 031170 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import java.lang.reflect.Constructor;
import net.sf.cglib.core.*;
import net.sf.cglib.transform.*;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Type;
import org.objectweb.asm.ClassVisitor;
public class UndeclaredThrowableTransformer extends ClassEmitterTransformer {
private Type wrapper;
public UndeclaredThrowableTransformer(Class wrapper) {
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();
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");
}
public CodeEmitter begin_method(int access, final Signature sig, final Type[] exceptions) {
CodeEmitter e = super.begin_method(access, sig, exceptions);
if (TypeUtils.isAbstract(access) || sig.equals(Constants.SIG_STATIC)) {
return e;
}
return new CodeEmitter(e) {
private Block handler;
/* init */ {
handler = begin_block();
}
public void visitMaxs(int maxStack, int maxLocals) {
handler.end();
EmitUtils.wrap_undeclared_throwable(this, handler, exceptions, wrapper);
super.visitMaxs(maxStack, maxLocals);
}
};
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/impl/InterceptFieldTransformer.java 0000644 0001750 0001750 00000017347 12250620400 030161 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform.impl;
import net.sf.cglib.transform.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
/**
* @author Juozas Baliuka, Chris Nokleberg
*/
public class InterceptFieldTransformer extends ClassEmitterTransformer {
private static final String CALLBACK_FIELD = "$CGLIB_READ_WRITE_CALLBACK";
private static final Type CALLBACK =
TypeUtils.parseType("net.sf.cglib.transform.impl.InterceptFieldCallback");
private static final Type ENABLED =
TypeUtils.parseType("net.sf.cglib.transform.impl.InterceptFieldEnabled");
private static final Signature ENABLED_SET =
new Signature("setInterceptFieldCallback", Type.VOID_TYPE, new Type[]{ CALLBACK });
private static final Signature ENABLED_GET =
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) {
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,
null);
CodeEmitter e;
e = super.begin_method(Constants.ACC_PUBLIC, ENABLED_GET, null);
e.load_this();
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);
e.putfield(CALLBACK_FIELD);
e.return_value();
e.end_method();
} else {
super.begin_class(version, access, className, superType, interfaces, sourceFile);
}
}
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)) {
addReadMethod(name, type);
}
if (filter.acceptWrite(getClassType(), name)) {
addWriteMethod(name, type);
}
}
}
private void addReadMethod(String name, Type type) {
CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC,
readMethodSig(name, type.getDescriptor()),
null);
e.load_this();
e.getfield(name);
e.load_this();
e.invoke_interface(ENABLED,ENABLED_GET);
Label intercept = e.make_label();
e.ifnonnull(intercept);
e.return_value();
e.mark(intercept);
Local result = e.make_local(type);
e.store_local(result);
e.load_this();
e.invoke_interface(ENABLED,ENABLED_GET);
e.load_this();
e.push(name);
e.load_local(result);
e.invoke_interface(CALLBACK, readCallbackSig(type));
if (!TypeUtils.isPrimitive(type)) {
e.checkcast(type);
}
e.return_value();
e.end_method();
}
private void addWriteMethod(String name, Type type) {
CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC,
writeMethodSig(name, type.getDescriptor()),
null);
e.load_this();
e.dup();
e.invoke_interface(ENABLED,ENABLED_GET);
Label skip = e.make_label();
e.ifnull(skip);
e.load_this();
e.invoke_interface(ENABLED,ENABLED_GET);
e.load_this();
e.push(name);
e.load_this();
e.getfield(name);
e.load_arg(0);
e.invoke_interface(CALLBACK, writeCallbackSig(type));
if (!TypeUtils.isPrimitive(type)) {
e.checkcast(type);
}
Label go = e.make_label();
e.goTo(go);
e.mark(skip);
e.load_arg(0);
e.mark(go);
e.putfield(name);
e.return_value();
e.end_method();
}
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) {
Type towner = TypeUtils.fromInternalName(owner);
switch (opcode) {
case Constants.GETFIELD:
if (filter.acceptRead(towner, name)) {
helper(towner, readMethodSig(name, desc));
return;
}
break;
case Constants.PUTFIELD:
if (filter.acceptWrite(towner, name)) {
helper(towner, writeMethodSig(name, desc));
return;
}
break;
}
super.visitFieldInsn(opcode, owner, name, desc);
}
private void helper(Type owner, Signature sig) {
invoke_virtual(owner, sig);
}
};
}
private static Signature readMethodSig(String name, String desc) {
return new Signature("$cglib_read_" + name, "()" + desc);
}
private static Signature writeMethodSig(String name, String desc) {
return new Signature("$cglib_write_" + name, "(" + desc + ")V");
}
private static Signature readCallbackSig(Type type) {
Type remap = remap(type);
return new Signature("read" + callbackName(remap),
remap,
new Type[]{ Constants.TYPE_OBJECT,
Constants.TYPE_STRING,
remap });
}
private static Signature writeCallbackSig(Type type) {
Type remap = remap(type);
return new Signature("write" + callbackName(remap),
remap,
new Type[]{ Constants.TYPE_OBJECT,
Constants.TYPE_STRING,
remap,
remap });
}
private static Type remap(Type type) {
switch (type.getSort()) {
case Type.OBJECT:
case Type.ARRAY:
return Constants.TYPE_OBJECT;
default:
return type;
}
}
private static String callbackName(Type type) {
return (type == Constants.TYPE_OBJECT) ?
"Object" :
TypeUtils.upperFirst(TypeUtils.getClassName(type));
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/MethodVisitorTee.java 0000644 0001750 0001750 00000012467 12250620400 025330 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import org.objectweb.asm.*;
public class MethodVisitorTee extends MethodVisitor {
private final MethodVisitor mv1;
private final MethodVisitor mv2;
public MethodVisitorTee(MethodVisitor mv1, MethodVisitor mv2) {
super(Opcodes.ASM4);
this.mv1 = mv1;
this.mv2 = mv2;
}
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() {
return AnnotationVisitorTee.getInstance(mv1.visitAnnotationDefault(),
mv2.visitAnnotationDefault());
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitAnnotation(desc, visible),
mv2.visitAnnotation(desc, visible));
}
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) {
mv1.visitAttribute(attr);
mv2.visitAttribute(attr);
}
public void visitCode() {
mv1.visitCode();
mv2.visitCode();
}
public void visitInsn(int opcode) {
mv1.visitInsn(opcode);
mv2.visitInsn(opcode);
}
public void visitIntInsn(int opcode, int operand) {
mv1.visitIntInsn(opcode, operand);
mv2.visitIntInsn(opcode, operand);
}
public void visitVarInsn(int opcode, int var) {
mv1.visitVarInsn(opcode, var);
mv2.visitVarInsn(opcode, var);
}
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) {
mv1.visitFieldInsn(opcode, owner, name, desc);
mv2.visitFieldInsn(opcode, owner, name, desc);
}
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 visitJumpInsn(int opcode, Label label) {
mv1.visitJumpInsn(opcode, label);
mv2.visitJumpInsn(opcode, label);
}
public void visitLabel(Label label) {
mv1.visitLabel(label);
mv2.visitLabel(label);
}
public void visitLdcInsn(Object cst) {
mv1.visitLdcInsn(cst);
mv2.visitLdcInsn(cst);
}
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[]) {
mv1.visitTableSwitchInsn(min, max, dflt, labels);
mv2.visitTableSwitchInsn(min, max, dflt, labels);
}
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) {
mv1.visitMultiANewArrayInsn(desc, dims);
mv2.visitMultiANewArrayInsn(desc, dims);
}
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) {
mv1.visitLocalVariable(name, desc, signature, start, end, index);
mv2.visitLocalVariable(name, desc, signature, start, end, index);
}
public void visitLineNumber(int line, Label start) {
mv1.visitLineNumber(line, start);
mv2.visitLineNumber(line, start);
}
public void visitMaxs(int maxStack, int maxLocals) {
mv1.visitMaxs(maxStack, maxLocals);
mv2.visitMaxs(maxStack, maxLocals);
}
public void visitEnd() {
mv1.visitEnd();
mv2.visitEnd();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/transform/TransformingClassLoader.java 0000644 0001750 0001750 00000002355 10066633126 026667 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.transform;
import java.util.*;
import net.sf.cglib.core.ClassGenerator;
import org.objectweb.asm.*;
public class TransformingClassLoader extends AbstractClassLoader {
private ClassTransformerFactory t;
public TransformingClassLoader(ClassLoader parent, ClassFilter filter, ClassTransformerFactory t) {
super(parent, parent, filter);
this.t = t;
}
protected ClassGenerator getGenerator(ClassReader r) {
ClassTransformer t2 = (ClassTransformer)t.newInstance();
return new TransformingClassGenerator(super.getGenerator(r), t2);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/ 0000755 0001750 0001750 00000000000 12250627450 020306 5 ustar miguel miguel cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BeanCopier.java 0000644 0001750 0001750 00000015047 10402432050 023152 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
import java.util.*;
/**
* @author Chris Nokleberg
*/
abstract public class BeanCopier
{
private static final BeanCopierKey KEY_FACTORY =
(BeanCopierKey)KeyFactory.create(BeanCopierKey.class);
private static final Type CONVERTER =
TypeUtils.parseType("net.sf.cglib.core.Converter");
private static final Type BEAN_COPIER =
TypeUtils.parseType("net.sf.cglib.beans.BeanCopier");
private static final Signature COPY =
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);
}
public static BeanCopier create(Class source, Class target, boolean useConverter) {
Generator gen = new Generator();
gen.setSource(source);
gen.setTarget(target);
gen.setUseConverter(useConverter);
return gen.create();
}
abstract public void copy(Object from, Object to, Converter converter);
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(BeanCopier.class.getName());
private Class source;
private Class target;
private boolean useConverter;
public Generator() {
super(SOURCE);
}
public void setSource(Class source) {
if(!Modifier.isPublic(source.getModifiers())){
setNamePrefix(source.getName());
}
this.source = source;
}
public void setTarget(Class target) {
if(!Modifier.isPublic(target.getModifiers())){
setNamePrefix(target.getName());
}
this.target = target;
}
public void setUseConverter(boolean useConverter) {
this.useConverter = useConverter;
}
protected ClassLoader getDefaultClassLoader() {
return source.getClassLoader();
}
public BeanCopier create() {
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
return (BeanCopier)super.create(key);
}
public void generateClass(ClassVisitor v) {
Type sourceType = Type.getType(source);
Type targetType = Type.getType(target);
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
BEAN_COPIER,
null,
Constants.SOURCE_FILE);
EmitUtils.null_constructor(ce);
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null);
PropertyDescriptor[] getters = ReflectUtils.getBeanGetters(source);
PropertyDescriptor[] setters = ReflectUtils.getBeanGetters(target);
Map names = new HashMap();
for (int i = 0; i < getters.length; i++) {
names.put(getters[i].getName(), getters[i]);
}
Local targetLocal = e.make_local();
Local sourceLocal = e.make_local();
if (useConverter) {
e.load_arg(1);
e.checkcast(targetType);
e.store_local(targetLocal);
e.load_arg(0);
e.checkcast(sourceType);
e.store_local(sourceLocal);
} else {
e.load_arg(1);
e.checkcast(targetType);
e.load_arg(0);
e.checkcast(sourceType);
}
for (int i = 0; i < setters.length; i++) {
PropertyDescriptor setter = setters[i];
PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName());
if (getter != null) {
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod());
if (useConverter) {
Type setterType = write.getSignature().getArgumentTypes()[0];
e.load_local(targetLocal);
e.load_arg(2);
e.load_local(sourceLocal);
e.invoke(read);
e.box(read.getSignature().getReturnType());
EmitUtils.load_class(e, setterType);
e.push(write.getSignature().getName());
e.invoke_interface(CONVERTER, CONVERT);
e.unbox_or_zero(setterType);
e.invoke(write);
} else if (compatible(getter, setter)) {
e.dup2();
e.invoke(read);
e.invoke(write);
}
}
}
e.return_value();
e.end_method();
ce.end_class();
}
private static boolean compatible(PropertyDescriptor getter, PropertyDescriptor setter) {
// TODO: allow automatic widening conversions?
return setter.getPropertyType().isAssignableFrom(getter.getPropertyType());
}
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type);
}
protected Object nextInstance(Object instance) {
return instance;
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BulkBean.java 0000644 0001750 0001750 00000010577 10312456122 022637 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
/**
* @author Juozas Baliuka
*/
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);
public Object[] getPropertyValues(Object bean) {
Object[] values = new Object[getters.length];
getPropertyValues(bean, values);
return values;
}
public Class[] getPropertyTypes() {
return (Class[])types.clone();
}
public String[] getGetters() {
return (String[])getters.clone();
}
public String[] getSetters() {
return (String[])setters.clone();
}
public static BulkBean create(Class target, String[] getters, String[] setters, Class[] types) {
Generator gen = new Generator();
gen.setTarget(target);
gen.setGetters(getters);
gen.setSetters(setters);
gen.setTypes(types);
return gen.create();
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(BulkBean.class.getName());
private Class target;
private String[] getters;
private String[] setters;
private Class[] types;
public Generator() {
super(SOURCE);
}
public void setTarget(Class target) {
this.target = target;
}
public void setGetters(String[] getters) {
this.getters = getters;
}
public void setSetters(String[] setters) {
this.setters = setters;
}
public void setTypes(Class[] types) {
this.types = types;
}
protected ClassLoader getDefaultClassLoader() {
return target.getClassLoader();
}
public BulkBean create() {
setNamePrefix(target.getName());
String targetClassName = target.getName();
String[] typeClassNames = ReflectUtils.getNames(types);
Object key = KEY_FACTORY.newInstance(targetClassName, getters, setters, typeClassNames);
return (BulkBean)super.create(key);
}
public void generateClass(ClassVisitor v) throws Exception {
new BulkBeanEmitter(v, getClassName(), target, getters, setters, types);
}
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) {
return instance;
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BulkBeanException.java 0000644 0001750 0001750 00000002346 10066633132 024515 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import net.sf.cglib.core.CodeGenerationException;
public class BulkBeanException extends RuntimeException
{
private int index;
private Throwable cause;
public BulkBeanException(String message, int index) {
super(message);
this.index = index;
}
public BulkBeanException(Throwable cause, int index) {
super(cause.getMessage());
this.index = index;
this.cause = cause;
}
public int getIndex() {
return index;
}
public Throwable getCause() {
return cause;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/FixedKeySet.java 0000644 0001750 0001750 00000002117 10066633132 023333 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.util.*;
public /* need it for class loading */ class FixedKeySet extends AbstractSet {
private Set set;
private int size;
public FixedKeySet(String[] keys) {
size = keys.length;
set = Collections.unmodifiableSet(new HashSet(Arrays.asList(keys)));
}
public Iterator iterator() {
return set.iterator();
}
public int size() {
return size;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BulkBeanEmitter.java 0000644 0001750 0001750 00000014701 10402432050 024154 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
class BulkBeanEmitter extends ClassEmitter {
private static final Signature GET_PROPERTY_VALUES =
TypeUtils.parseSignature("void getPropertyValues(Object, Object[])");
private static final Signature SET_PROPERTY_VALUES =
TypeUtils.parseSignature("void setPropertyValues(Object, Object[])");
private static final Signature CSTRUCT_EXCEPTION =
TypeUtils.parseConstructor("Throwable, int");
private static final Type BULK_BEAN =
TypeUtils.parseType("net.sf.cglib.beans.BulkBean");
private static final Type BULK_BEAN_EXCEPTION =
TypeUtils.parseType("net.sf.cglib.beans.BulkBeanException");
public BulkBeanEmitter(ClassVisitor v,
String className,
Class target,
String[] getterNames,
String[] setterNames,
Class[] types) {
super(v);
Method[] getters = new Method[getterNames.length];
Method[] setters = new Method[setterNames.length];
validate(target, getterNames, setterNames, types, getters, setters);
begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BULK_BEAN, null, Constants.SOURCE_FILE);
EmitUtils.null_constructor(this);
generateGet(target, getters);
generateSet(target, setters);
end_class();
}
private void generateGet(final Class target, final Method[] getters) {
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null);
if (getters.length >= 0) {
e.load_arg(0);
e.checkcast(Type.getType(target));
Local bean = e.make_local();
e.store_local(bean);
for (int i = 0; i < getters.length; i++) {
if (getters[i] != null) {
MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]);
e.load_arg(1);
e.push(i);
e.load_local(bean);
e.invoke(getter);
e.box(getter.getSignature().getReturnType());
e.aastore();
}
}
}
e.return_value();
e.end_method();
}
private void generateSet(final Class target, final Method[] setters) {
// setPropertyValues
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null);
if (setters.length > 0) {
Local index = e.make_local(Type.INT_TYPE);
e.push(0);
e.store_local(index);
e.load_arg(0);
e.checkcast(Type.getType(target));
e.load_arg(1);
Block handler = e.begin_block();
int lastIndex = 0;
for (int i = 0; i < setters.length; i++) {
if (setters[i] != null) {
MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
int diff = i - lastIndex;
if (diff > 0) {
e.iinc(index, diff);
lastIndex = i;
}
e.dup2();
e.aaload(i);
e.unbox(setter.getSignature().getArgumentTypes()[0]);
e.invoke(setter);
}
}
handler.end();
e.return_value();
e.catch_exception(handler, Constants.TYPE_THROWABLE);
e.new_instance(BULK_BEAN_EXCEPTION);
e.dup_x1();
e.swap();
e.load_local(index);
e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION);
e.athrow();
} else {
e.return_value();
}
e.end_method();
}
private static void validate(Class target,
String[] getters,
String[] setters,
Class[] types,
Method[] getters_out,
Method[] setters_out) {
int i = -1;
if (setters.length != types.length || getters.length != types.length) {
throw new BulkBeanException("accessor array length must be equal type array length", i);
}
try {
for (i = 0; i < types.length; i++) {
if (getters[i] != null) {
Method method = ReflectUtils.findDeclaredMethod(target, getters[i], null);
if (method.getReturnType() != types[i]) {
throw new BulkBeanException("Specified type " + types[i] +
" does not match declared type " + method.getReturnType(), i);
}
if (Modifier.isPrivate(method.getModifiers())) {
throw new BulkBeanException("Property is private", i);
}
getters_out[i] = method;
}
if (setters[i] != null) {
Method method = ReflectUtils.findDeclaredMethod(target, setters[i], new Class[]{ types[i] });
if (Modifier.isPrivate(method.getModifiers()) ){
throw new BulkBeanException("Property is private", i);
}
setters_out[i] = method;
}
}
} catch (NoSuchMethodException e) {
throw new BulkBeanException("Cannot find specified property", i);
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BeanMapEmitter.java 0000644 0001750 0001750 00000017205 10402432050 023776 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.beans.*;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
class BeanMapEmitter extends ClassEmitter {
private static final Type BEAN_MAP =
TypeUtils.parseType("net.sf.cglib.beans.BeanMap");
private static final Type FIXED_KEY_SET =
TypeUtils.parseType("net.sf.cglib.beans.FixedKeySet");
private static final Signature CSTRUCT_OBJECT =
TypeUtils.parseConstructor("Object");
private static final Signature CSTRUCT_STRING_ARRAY =
TypeUtils.parseConstructor("String[]");
private static final Signature BEAN_MAP_GET =
TypeUtils.parseSignature("Object get(Object, Object)");
private static final Signature BEAN_MAP_PUT =
TypeUtils.parseSignature("Object put(Object, Object, Object)");
private static final Signature KEY_SET =
TypeUtils.parseSignature("java.util.Set keySet()");
private static final Signature NEW_INSTANCE =
new Signature("newInstance", BEAN_MAP, new Type[]{ Constants.TYPE_OBJECT });
private static final Signature GET_PROPERTY_TYPE =
TypeUtils.parseSignature("Class getPropertyType(String)");
public BeanMapEmitter(ClassVisitor v, String className, Class type, int require) {
super(v);
begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BEAN_MAP, null, Constants.SOURCE_FILE);
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();
allProps.putAll(getters);
allProps.putAll(setters);
if (require != 0) {
for (Iterator it = allProps.keySet().iterator(); it.hasNext();) {
String name = (String)it.next();
if ((((require & BeanMap.REQUIRE_GETTER) != 0) && !getters.containsKey(name)) ||
(((require & BeanMap.REQUIRE_SETTER) != 0) && !setters.containsKey(name))) {
it.remove();
getters.remove(name);
setters.remove(name);
}
}
}
generateGet(type, getters);
generatePut(type, setters);
String[] allNames = getNames(allProps);
generateKeySet(allNames);
generateGetPropertyType(allProps, allNames);
end_class();
}
private Map makePropertyMap(PropertyDescriptor[] props) {
Map names = new HashMap();
for (int i = 0; i < props.length; i++) {
names.put(((PropertyDescriptor)props[i]).getName(), props[i]);
}
return names;
}
private String[] getNames(Map propertyMap) {
return (String[])propertyMap.keySet().toArray(new String[propertyMap.size()]);
}
private void generateConstructor() {
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null);
e.load_this();
e.load_arg(0);
e.super_invoke_constructor(CSTRUCT_OBJECT);
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);
e.checkcast(Type.getType(type));
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) {
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() {
e.aconst_null();
e.return_value();
}
});
e.end_method();
}
private void generatePut(Class type, final Map setters) {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_PUT, null);
e.load_arg(0);
e.checkcast(Type.getType(type));
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) {
PropertyDescriptor pd = (PropertyDescriptor)setters.get(key);
if (pd.getReadMethod() == null) {
e.aconst_null();
} else {
MethodInfo read = ReflectUtils.getMethodInfo(pd.getReadMethod());
e.dup();
e.invoke(read);
e.box(read.getSignature().getReturnType());
}
e.swap(); // move old value behind bean
e.load_arg(2); // new value
MethodInfo write = ReflectUtils.getMethodInfo(pd.getWriteMethod());
e.unbox(write.getSignature().getArgumentTypes()[0]);
e.invoke(write);
e.return_value();
}
public void processDefault() {
// fall-through
}
});
e.aconst_null();
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);
CodeEmitter e = begin_static();
e.new_instance(FIXED_KEY_SET);
e.dup();
EmitUtils.push_array(e, allNames);
e.invoke_constructor(FIXED_KEY_SET, CSTRUCT_STRING_ARRAY);
e.putfield("keys");
e.return_value();
e.end_method();
// keySet
e = begin_method(Constants.ACC_PUBLIC, KEY_SET, null);
e.load_this();
e.getfield("keys");
e.return_value();
e.end_method();
}
private void generateGetPropertyType(final Map allProps, String[] allNames) {
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) {
PropertyDescriptor pd = (PropertyDescriptor)allProps.get(key);
EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
e.return_value();
}
public void processDefault() {
e.aconst_null();
e.return_value();
}
});
e.end_method();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/ImmutableBean.java 0000644 0001750 0001750 00000010502 10402432050 023637 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
/**
* @author Chris Nokleberg
*/
public class ImmutableBean
{
private static final Type ILLEGAL_STATE_EXCEPTION =
TypeUtils.parseType("IllegalStateException");
private static final Signature CSTRUCT_OBJECT =
TypeUtils.parseConstructor("Object");
private static final Class[] OBJECT_CLASSES = { Object.class };
private static final String FIELD_NAME = "CGLIB$RWBean";
private ImmutableBean() {
}
public static Object create(Object bean) {
Generator gen = new Generator();
gen.setBean(bean);
return gen.create();
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(ImmutableBean.class.getName());
private Object bean;
private Class target;
public Generator() {
super(SOURCE);
}
public void setBean(Object bean) {
this.bean = bean;
target = bean.getClass();
}
protected ClassLoader getDefaultClassLoader() {
return target.getClassLoader();
}
public Object create() {
String name = target.getName();
setNamePrefix(name);
return super.create(name);
}
public void generateClass(ClassVisitor v) {
Type targetType = Type.getType(target);
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
targetType,
null,
Constants.SOURCE_FILE);
ce.declare_field(Constants.ACC_FINAL | Constants.ACC_PRIVATE, FIELD_NAME, targetType, null);
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null);
e.load_this();
e.super_invoke_constructor();
e.load_this();
e.load_arg(0);
e.checkcast(targetType);
e.putfield(FIELD_NAME);
e.return_value();
e.end_method();
PropertyDescriptor[] descriptors = ReflectUtils.getBeanProperties(target);
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]);
e = EmitUtils.begin_method(ce, getter, Constants.ACC_PUBLIC);
e.load_this();
e.getfield(FIELD_NAME);
e.invoke(getter);
e.return_value();
e.end_method();
}
for (int i = 0; i < setters.length; i++) {
MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
e = EmitUtils.begin_method(ce, setter, Constants.ACC_PUBLIC);
e.throw_exception(ILLEGAL_STATE_EXCEPTION, "Bean is immutable");
e.end_method();
}
ce.end_class();
}
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type, OBJECT_CLASSES, new Object[]{ bean });
}
// TODO: optimize
protected Object nextInstance(Object instance) {
return firstInstance(instance.getClass());
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BeanMap.java 0000644 0001750 0001750 00000024145 10066633132 022457 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.beans.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
/**
* A Map
-based view of a JavaBean. The default set of keys is the
* union of all property names (getters or setters). An attempt to set
* a read-only property will be ignored, and write-only properties will
* be returned as null
. Removal of objects is not a
* supported (the key set is fixed).
* @author Chris Nokleberg
*/
abstract public class BeanMap implements Map {
/**
* Limit the properties reflected in the key set of the map
* to readable properties.
* @see BeanMap.Generator#setRequire
*/
public static final int REQUIRE_GETTER = 1;
/**
* Limit the properties reflected in the key set of the map
* to writable properties.
* @see BeanMap.Generator#setRequire
*/
public static final int REQUIRE_SETTER = 2;
/**
* Helper method to create a new BeanMap
. For finer
* control over the generated instance, use a new instance of
* BeanMap.Generator
instead of this static method.
* @param bean the JavaBean underlying the map
* @return a new BeanMap
instance
*/
public static BeanMap create(Object bean) {
Generator gen = new Generator();
gen.setBean(bean);
return gen.create();
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(BeanMap.class.getName());
private static final BeanMapKey KEY_FACTORY =
(BeanMapKey)KeyFactory.create(BeanMapKey.class, KeyFactory.CLASS_BY_NAME);
interface BeanMapKey {
public Object newInstance(Class type, int require);
}
private Object bean;
private Class beanClass;
private int require;
public Generator() {
super(SOURCE);
}
/**
* Set the bean that the generated map should reflect. The bean may be swapped
* out for another bean of the same type using {@link #setBean}.
* Calling this method overrides any value previously set using {@link #setBeanClass}.
* You must call either this method or {@link #setBeanClass} before {@link #create}.
* @param bean the initial bean
*/
public void setBean(Object bean) {
this.bean = bean;
if (bean != null)
beanClass = bean.getClass();
}
/**
* Set the class of the bean that the generated map should support.
* You must call either this method or {@link #setBeanClass} before {@link #create}.
* @param beanClass the class of the bean
*/
public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}
/**
* Limit the properties reflected by the generated map.
* @param require any combination of {@link #REQUIRE_GETTER} and
* {@link #REQUIRE_SETTER}; default is zero (any property allowed)
*/
public void setRequire(int require) {
this.require = require;
}
protected ClassLoader getDefaultClassLoader() {
return beanClass.getClassLoader();
}
/**
* Create a new instance of the BeanMap
. An existing
* generated class will be reused if possible.
*/
public BeanMap create() {
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 {
new BeanMapEmitter(v, getClassName(), beanClass, require);
}
protected Object firstInstance(Class type) {
return ((BeanMap)ReflectUtils.newInstance(type)).newInstance(bean);
}
protected Object nextInstance(Object instance) {
return ((BeanMap)instance).newInstance(bean);
}
}
/**
* Create a new BeanMap
instance using the specified bean.
* This is faster than using the {@link #create} static method.
* @param bean the JavaBean underlying the map
* @return a new BeanMap
instance
*/
abstract public BeanMap newInstance(Object bean);
/**
* Get the type of a property.
* @param name the name of the JavaBean property
* @return the type of the property, or null if the property does not exist
*/
abstract public Class getPropertyType(String name);
protected Object bean;
protected BeanMap() {
}
protected BeanMap(Object bean) {
setBean(bean);
}
public Object get(Object key) {
return get(bean, key);
}
public Object put(Object key, Object value) {
return put(bean, key, value);
}
/**
* Get the property of a bean. This allows a BeanMap
* to be used statically for multiple beans--the bean instance tied to the
* map is ignored and the bean passed to this method is used instead.
* @param bean the bean to query; must be compatible with the type of
* this BeanMap
* @param key must be a String
* @return the current value, or null if there is no matching property
*/
abstract public Object get(Object bean, Object key);
/**
* Set the property of a bean. This allows a BeanMap
* to be used statically for multiple beans--the bean instance tied to the
* map is ignored and the bean passed to this method is used instead.
* @param key must be a String
* @return the old value, if there was one, or null
*/
abstract public Object put(Object bean, Object key, Object value);
/**
* Change the underlying bean this map should use.
* @param bean the new JavaBean
* @see #getBean
*/
public void setBean(Object bean) {
this.bean = bean;
}
/**
* Return the bean currently in use by this map.
* @return the current JavaBean
* @see #setBean
*/
public Object getBean() {
return bean;
}
public void clear() {
throw new UnsupportedOperationException();
}
public boolean containsKey(Object key) {
return keySet().contains(key);
}
public boolean containsValue(Object value) {
for (Iterator it = keySet().iterator(); it.hasNext();) {
Object v = get(it.next());
if (((value == null) && (v == null)) || value.equals(v))
return true;
}
return false;
}
public int size() {
return keySet().size();
}
public boolean isEmpty() {
return size() == 0;
}
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();
put(key, t.get(key));
}
}
public boolean equals(Object o) {
if (o == null || !(o instanceof Map)) {
return false;
}
Map other = (Map)o;
if (size() != other.size()) {
return false;
}
for (Iterator it = keySet().iterator(); it.hasNext();) {
Object key = it.next();
if (!other.containsKey(key)) {
return false;
}
Object v1 = get(key);
Object v2 = other.get(key);
if (!((v1 == null) ? v2 == null : v1.equals(v2))) {
return false;
}
}
return true;
}
public int hashCode() {
int code = 0;
for (Iterator it = keySet().iterator(); it.hasNext();) {
Object key = it.next();
Object value = get(key);
code += ((key == null) ? 0 : key.hashCode()) ^
((value == null) ? 0 : value.hashCode());
}
return code;
}
// TODO: optimize
public Set entrySet() {
HashMap copy = new HashMap();
for (Iterator it = keySet().iterator(); it.hasNext();) {
Object key = it.next();
copy.put(key, get(key));
}
return Collections.unmodifiableMap(copy).entrySet();
}
public Collection values() {
Set keys = keySet();
List values = new ArrayList(keys.size());
for (Iterator it = keys.iterator(); it.hasNext();) {
values.add(get(it.next()));
}
return Collections.unmodifiableCollection(values);
}
/*
* @see java.util.AbstractMap#toString
*/
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append('{');
for (Iterator it = keySet().iterator(); it.hasNext();) {
Object key = it.next();
sb.append(key);
sb.append('=');
sb.append(get(key));
if (it.hasNext()) {
sb.append(", ");
}
}
sb.append('}');
return sb.toString();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/beans/BeanGenerator.java 0000644 0001750 0001750 00000011362 10305457236 023672 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.beans;
import java.beans.PropertyDescriptor;
import java.util.*;
import net.sf.cglib.core.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
/**
* @author Juozas Baliuka, Chris Nokleberg
*/
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);
}
private Class superclass;
private Map props = new HashMap();
private boolean classOnly;
public BeanGenerator() {
super(SOURCE);
}
/**
* Set the class which the generated class will extend. The class
* must not be declared as final, and must have a non-private
* no-argument constructor.
* @param superclass class to extend, or null to extend Object
*/
public void setSuperclass(Class superclass) {
if (superclass != null && superclass.equals(Object.class)) {
superclass = null;
}
this.superclass = superclass;
}
public void addProperty(String name, Class type) {
if (props.containsKey(name)) {
throw new IllegalArgumentException("Duplicate property name \"" + name + "\"");
}
props.put(name, Type.getType(type));
}
protected ClassLoader getDefaultClassLoader() {
if (superclass != null) {
return superclass.getClassLoader();
} else {
return null;
}
}
public Object create() {
classOnly = false;
return createHelper();
}
public Object createClass() {
classOnly = true;
return createHelper();
}
private Object createHelper() {
if (superclass != null) {
setNamePrefix(superclass.getName());
}
String superName = (superclass != null) ? superclass.getName() : "java.lang.Object";
Object key = KEY_FACTORY.newInstance(superName, props);
return super.create(key);
}
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];
for (int i = 0; i < size; i++) {
types[i] = (Type)props.get(names[i]);
}
ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
superclass != null ? Type.getType(superclass) : Constants.TYPE_OBJECT,
null,
null);
EmitUtils.null_constructor(ce);
EmitUtils.add_properties(ce, names, types);
ce.end_class();
}
protected Object firstInstance(Class type) {
if (classOnly) {
return type;
} else {
return ReflectUtils.newInstance(type);
}
}
protected Object nextInstance(Object instance) {
Class protoclass = (instance instanceof Class) ? (Class)instance : instance.getClass();
if (classOnly) {
return protoclass;
} else {
return ReflectUtils.newInstance(protoclass);
}
}
public static void addProperties(BeanGenerator gen, Map props) {
for (Iterator it = props.keySet().iterator(); it.hasNext();) {
String name = (String)it.next();
gen.addProperty(name, (Class)props.get(name));
}
}
public static void addProperties(BeanGenerator gen, Class type) {
addProperties(gen, ReflectUtils.getBeanProperties(type));
}
public static void addProperties(BeanGenerator gen, PropertyDescriptor[] descriptors) {
for (int i = 0; i < descriptors.length; i++) {
gen.addProperty(descriptors[i].getName(), descriptors[i].getPropertyType());
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ 0000755 0001750 0001750 00000000000 12250627450 020146 5 ustar miguel miguel cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/Transformer.java 0000644 0001750 0001750 00000001336 10066633130 023311 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
public interface Transformer {
Object transform(Object value);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/AbstractClassGenerator.java 0000644 0001750 0001750 00000020422 10315775700 025413 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.io.*;
import java.util.*;
import java.lang.ref.*;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
/**
* Abstract class for all code-generating CGLIB utilities.
* In addition to caching generated classes for performance, it provides hooks for
* customizing the ClassLoader
, name of the generated class, and transformations
* applied before generation.
*/
abstract public class AbstractClassGenerator
implements ClassGenerator
{
private static final Object NAME_KEY = new Object();
private static final ThreadLocal CURRENT = new ThreadLocal();
private GeneratorStrategy strategy = DefaultGeneratorStrategy.INSTANCE;
private NamingPolicy namingPolicy = DefaultNamingPolicy.INSTANCE;
private Source source;
private ClassLoader classLoader;
private String namePrefix;
private Object key;
private boolean useCache = true;
private String className;
private boolean attemptLoad;
protected static class Source {
String name;
Map cache = new WeakHashMap();
public Source(String name) {
this.name = name;
}
}
protected AbstractClassGenerator(Source source) {
this.source = source;
}
protected void setNamePrefix(String namePrefix) {
this.namePrefix = namePrefix;
}
final protected String getClassName() {
if (className == null)
className = getClassName(getClassLoader());
return className;
}
private String getClassName(final ClassLoader loader) {
final Set nameCache = getClassNameCache(loader);
return namingPolicy.getClassName(namePrefix, source.name, key, new Predicate() {
public boolean evaluate(Object arg) {
return nameCache.contains(arg);
}
});
}
private Set getClassNameCache(ClassLoader loader) {
return (Set)((Map)source.cache.get(loader)).get(NAME_KEY);
}
/**
* Set the ClassLoader
in which the class will be generated.
* Concrete subclasses of AbstractClassGenerator
(such as Enhancer
)
* will try to choose an appropriate default if this is unset.
* ClassLoader
using a WeakHashMap
, to allow
* the generated classes to be removed when the associated loader is garbage collected.
* @param classLoader the loader to generate the new class with, or null to use the default
*/
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
/**
* Override the default naming policy.
* @see DefaultNamingPolicy
* @param namingPolicy the custom policy, or null to use the default
*/
public void setNamingPolicy(NamingPolicy namingPolicy) {
if (namingPolicy == null)
namingPolicy = DefaultNamingPolicy.INSTANCE;
this.namingPolicy = namingPolicy;
}
/**
* @see #setNamingPolicy
*/
public NamingPolicy getNamingPolicy() {
return namingPolicy;
}
/**
* Whether use and update the static cache of generated classes
* for a class with the same properties. Default is true
.
*/
public void setUseCache(boolean useCache) {
this.useCache = useCache;
}
/**
* @see #setUseCache
*/
public boolean getUseCache() {
return useCache;
}
/**
* If set, CGLIB will attempt to load classes from the specified
* ClassLoader
before generating them. Because generated
* class names are not guaranteed to be unique, the default is false
.
*/
public void setAttemptLoad(boolean attemptLoad) {
this.attemptLoad = attemptLoad;
}
public boolean getAttemptLoad() {
return attemptLoad;
}
/**
* Set the strategy to use to create the bytecode from this generator.
* By default an instance of {@see DefaultGeneratorStrategy} is used.
*/
public void setStrategy(GeneratorStrategy strategy) {
if (strategy == null)
strategy = DefaultGeneratorStrategy.INSTANCE;
this.strategy = strategy;
}
/**
* @see #setStrategy
*/
public GeneratorStrategy getStrategy() {
return strategy;
}
/**
* Used internally by CGLIB. Returns the AbstractClassGenerator
* that is being used to generate a class in the current thread.
*/
public static AbstractClassGenerator getCurrent() {
return (AbstractClassGenerator)CURRENT.get();
}
public ClassLoader getClassLoader() {
ClassLoader t = classLoader;
if (t == null) {
t = getDefaultClassLoader();
}
if (t == null) {
t = getClass().getClassLoader();
}
if (t == null) {
t = Thread.currentThread().getContextClassLoader();
}
if (t == null) {
throw new IllegalStateException("Cannot determine classloader");
}
return t;
}
abstract protected ClassLoader getDefaultClassLoader();
protected Object create(Object key) {
try {
Class gen = null;
synchronized (source) {
ClassLoader loader = getClassLoader();
Map cache2 = null;
cache2 = (Map)source.cache.get(loader);
if (cache2 == null) {
cache2 = new HashMap();
cache2.put(NAME_KEY, new HashSet());
source.cache.put(loader, cache2);
} else if (useCache) {
Reference ref = (Reference)cache2.get(key);
gen = (Class) (( ref == null ) ? null : ref.get());
}
if (gen == null) {
Object save = CURRENT.get();
CURRENT.set(this);
try {
this.key = key;
if (attemptLoad) {
try {
gen = loader.loadClass(getClassName());
} catch (ClassNotFoundException e) {
// ignore
}
}
if (gen == null) {
byte[] b = strategy.generate(this);
String className = ClassNameReader.getClassName(new ClassReader(b));
getClassNameCache(loader).add(className);
gen = ReflectUtils.defineClass(className, b, loader);
}
if (useCache) {
cache2.put(key, new WeakReference(gen));
}
return firstInstance(gen);
} finally {
CURRENT.set(save);
}
}
}
return firstInstance(gen);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
abstract protected Object firstInstance(Class type) throws Exception;
abstract protected Object nextInstance(Object instance) throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/VisibilityPredicate.java 0000644 0001750 0001750 00000003011 10066633130 024747 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.lang.reflect.*;
import org.objectweb.asm.Type;
public class VisibilityPredicate implements Predicate {
private boolean protectedOk;
private String pkg;
public VisibilityPredicate(Class source, boolean protectedOk) {
this.protectedOk = protectedOk;
pkg = TypeUtils.getPackageName(Type.getType(source));
}
public boolean evaluate(Object arg) {
int mod = (arg instanceof Member) ? ((Member)arg).getModifiers() : ((Integer)arg).intValue();
if (Modifier.isPrivate(mod)) {
return false;
} else if (Modifier.isPublic(mod)) {
return true;
} else if (Modifier.isProtected(mod)) {
return protectedOk;
} else {
return pkg.equals(TypeUtils.getPackageName(Type.getType(((Member)arg).getDeclaringClass())));
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ClassGenerator.java 0000644 0001750 0001750 00000001440 10066633132 023721 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.ClassVisitor;
public interface ClassGenerator {
void generateClass(ClassVisitor v) throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/LocalVariablesSorter.java 0000644 0001750 0001750 00000012645 12250620376 025103 0 ustar miguel miguel /***
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2005 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.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
*/
public class LocalVariablesSorter extends MethodVisitor {
/**
* Mapping from old to new local variable indexes. A local variable at index
* i of size 1 is remapped to 'mapping[2*i]', while a local variable at
* index i of size 2 is remapped to 'mapping[2*i+1]'.
*/
private static class State
{
int[] mapping = new int[40];
int nextLocal;
}
protected final int firstLocal;
private final State state;
public LocalVariablesSorter(
final int access,
final String desc,
final MethodVisitor mv)
{
super(Opcodes.ASM4, mv);
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();
}
firstLocal = state.nextLocal;
}
public LocalVariablesSorter(LocalVariablesSorter lvs) {
super(Opcodes.ASM4, lvs.mv);
state = lvs.state;
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;
}
mv.visitVarInsn(opcode, remap(var, size));
}
public void visitIincInsn(final int var, final int increment) {
mv.visitIincInsn(remap(var, 1), increment);
}
public void visitMaxs(final int maxStack, final int maxLocals) {
mv.visitMaxs(maxStack, state.nextLocal);
}
public void visitLocalVariable(
final String name,
final String desc,
final String signature,
final Label start,
final Label end,
final int index)
{
mv.visitLocalVariable(name, desc, signature, start, end, remap(index));
}
// -------------
protected int newLocal(final int size) {
int var = state.nextLocal;
state.nextLocal += size;
return var;
}
private int remap(final int var, final int size) {
if (var < firstLocal) {
return var;
}
int key = 2 * var + size - 1;
int length = state.mapping.length;
if (key >= length) {
int[] newMapping = new int[Math.max(2 * length, key + 1)];
System.arraycopy(state.mapping, 0, newMapping, 0, length);
state.mapping = newMapping;
}
int value = state.mapping[key];
if (value == 0) {
value = state.nextLocal + 1;
state.mapping[key] = value;
state.nextLocal += size;
}
return value - 1;
}
private int remap(final int var) {
if (var < firstLocal) {
return var;
}
int key = 2 * var;
int value = key < state.mapping.length ? state.mapping[key] : 0;
if (value == 0) {
value = key + 1 < state.mapping.length ? state.mapping[key + 1] : 0;
}
if (value == 0) {
throw new IllegalStateException("Unknown local variable " + var);
}
return value - 1;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/GeneratorStrategy.java 0000644 0001750 0001750 00000003466 10066633132 024470 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
/**
* The GeneratorStrategyClass
. By providing your
* own strategy you may examine or modify the generated class before
* it is loaded. Typically this will be accomplished by subclassing
* {@link DefaultGeneratorStrategy} and overriding the appropriate
* protected method.
* @see AbstractClassGenerator#setStrategy
*/
public interface GeneratorStrategy {
/**
* Generate the class.
* @param cg a class generator on which you can call {@link ClassGenerator#generateClass}
* @return a byte array containing the bits of a valid Class
*/
byte[] generate(ClassGenerator cg) throws Exception;
/**
* The GeneratorStrategy
in use does not currently, but may
* in the future, affect the caching of classes generated by {@link
* AbstractClassGenerator}, so this is a reminder that you should
* correctly implement equals
and hashCode
* to avoid generating too many classes.
*/
boolean equals(Object o);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ProcessArrayCallback.java 0000644 0001750 0001750 00000001411 10066633132 025035 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Type;
public interface ProcessArrayCallback {
void processElement(Type type);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/Signature.java 0000644 0001750 0001750 00000004046 10066633130 022751 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Type;
/**
* A representation of a method signature, containing the method name,
* return type, and parameter types.
*/
public class Signature {
private String name;
private String desc;
public Signature(String name, String desc) {
// TODO: better error checking
if (name.indexOf('(') >= 0) {
throw new IllegalArgumentException("Name '" + name + "' is invalid");
}
this.name = name;
this.desc = desc;
}
public Signature(String name, Type returnType, Type[] argumentTypes) {
this(name, Type.getMethodDescriptor(returnType, argumentTypes));
}
public String getName() {
return name;
}
public String getDescriptor() {
return desc;
}
public Type getReturnType() {
return Type.getReturnType(desc);
}
public Type[] getArgumentTypes() {
return Type.getArgumentTypes(desc);
}
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;
return name.equals(other.name) && desc.equals(other.desc);
}
public int hashCode() {
return name.hashCode() ^ desc.hashCode();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/DuplicatesPredicate.java 0000644 0001750 0001750 00000001647 10066633132 024734 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.lang.reflect.Method;
import java.util.*;
public class DuplicatesPredicate implements Predicate {
private Set unique = new HashSet();
public boolean evaluate(Object arg) {
return unique.add(MethodWrapper.create((Method)arg));
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/NamingPolicy.java 0000644 0001750 0001750 00000003750 10066633132 023404 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.util.Set;
/**
* Customize the generated class name for {@link AbstractClassGenerator}-based utilities.
*/
public interface NamingPolicy {
/**
* Choose a name for a generated class.
* @param prefix a dotted-name chosen by the generating class (possibly to put the generated class in a particular package)
* @param source the fully-qualified class name of the generating class (for example "net.sf.cglib.Enhancer")
* @param key A key object representing the state of the parameters; for caching to work properly, equal keys should result
* in the same generated class name. The default policy incorporates key.hashCode()
into the class name.
* @param names a predicate that returns true if the given classname has already been used in the same ClassLoader.
* @return the fully-qualified class name
*/
String getClassName(String prefix, String source, Object key, Predicate names);
/**
* The NamingPolicy
in use does not currently, but may
* in the future, affect the caching of classes generated by {@link
* AbstractClassGenerator}, so this is a reminder that you should
* correctly implement equals
and hashCode
* to avoid generating too many classes.
*/
boolean equals(Object o);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/TinyBitSet.java 0000644 0001750 0001750 00000003513 10066633130 023044 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
public class TinyBitSet {
private static int[] T = new int[256];
private int value = 0;
private static int gcount(int x) {
int c = 0;
while (x != 0) {
c++;
x &= (x - 1);
}
return c;
}
static {
for(int j = 0; j < 256; j++) {
T[j] = gcount(j);
}
}
private static int topbit(int i) {
int j;
for (j = 0; i != 0; i ^= j) {
j = i & -i;
}
return j;
}
private static int log2(int i) {
int j = 0;
for (j = 0; i != 0; i >>= 1) {
j++;
}
return j;
}
public int length() {
return log2(topbit(value));
}
public int cardinality() {
int w = value;
int c = 0;
while (w != 0) {
c += T[w & 255];
w >>= 8;
}
return c;
}
public boolean get(int index) {
return (value & (1 << index)) != 0;
}
public void set(int index) {
value |= (1 << index);
}
public void clear(int index) {
value &= ~(1 << index);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ClassInfo.java 0000644 0001750 0001750 00000002614 10066633132 022672 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Type;
abstract public class ClassInfo {
protected ClassInfo() {
}
abstract public Type getType();
abstract public Type getSuperType();
abstract public Type[] getInterfaces();
abstract public int getModifiers();
public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof ClassInfo))
return false;
return getType().equals(((ClassInfo)o).getType());
}
public int hashCode() {
return getType().hashCode();
}
public String toString() {
// TODO: include modifiers, superType, interfaces
return getType().getClassName();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/Constants.java 0000644 0001750 0001750 00000007000 10402432050 022745 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Type;
/**
* @author Juozas Baliuka baliuka@mwm.lt
* @version $Id: Constants.java,v 1.21 2006/03/05 02:43:19 herbyderby Exp $
*/
public interface Constants extends org.objectweb.asm.Opcodes {
public static final Class[] EMPTY_CLASS_ARRAY = {};
public static final Type[] TYPES_EMPTY = {};
public static final Signature SIG_STATIC =
TypeUtils.parseSignature("void equals
method for
* Objects. Arrays are recursively processed in the same manner.
*/
public static void not_equals(final CodeEmitter e, Type type, final Label notEquals, final Customizer customizer) {
(new ProcessArrayCallback() {
public void processElement(Type type) {
not_equals_helper(e, type, notEquals, customizer, this);
}
}).processElement(type);
}
private static void not_equals_helper(CodeEmitter e,
Type type,
Label notEquals,
Customizer customizer,
ProcessArrayCallback callback) {
if (TypeUtils.isPrimitive(type)) {
e.if_cmp(type, e.NE, notEquals);
} else {
Label end = e.make_label();
nullcmp(e, notEquals, end);
if (TypeUtils.isArray(type)) {
Label checkContents = e.make_label();
e.dup2();
e.arraylength();
e.swap();
e.arraylength();
e.if_icmp(e.EQ, checkContents);
e.pop2();
e.goTo(notEquals);
e.mark(checkContents);
EmitUtils.process_arrays(e, type, callback);
} else {
if (customizer != null) {
customizer.customize(e, type);
e.swap();
customizer.customize(e, type);
}
e.invoke_virtual(Constants.TYPE_OBJECT, EQUALS);
e.if_jump(e.EQ, notEquals);
}
e.mark(end);
}
}
/**
* If both objects on the top of the stack are non-null, does nothing.
* If one is null, or both are null, both are popped off and execution
* branches to the respective label.
* @param oneNull label to branch to if only one of the objects is null
* @param bothNull label to branch to if both of the objects are null
*/
private static void nullcmp(CodeEmitter e, Label oneNull, Label bothNull) {
e.dup2();
Label nonNull = e.make_label();
Label oneNullHelper = e.make_label();
Label end = e.make_label();
e.ifnonnull(nonNull);
e.ifnonnull(oneNullHelper);
e.pop2();
e.goTo(bothNull);
e.mark(nonNull);
e.ifnull(oneNullHelper);
e.goTo(end);
e.mark(oneNullHelper);
e.pop2();
e.goTo(oneNull);
e.mark(end);
}
/*
public static void to_string(CodeEmitter e,
Type type,
ArrayDelimiters delims,
Customizer customizer) {
e.new_instance(Constants.TYPE_STRING_BUFFER);
e.dup();
e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
e.swap();
append_string(e, type, delims, customizer);
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
}
*/
public static void append_string(final CodeEmitter e,
Type type,
final ArrayDelimiters delims,
final Customizer customizer) {
final ArrayDelimiters d = (delims != null) ? delims : DEFAULT_DELIMITERS;
ProcessArrayCallback callback = new ProcessArrayCallback() {
public void processElement(Type type) {
append_string_helper(e, type, d, customizer, this);
e.push(d.inside);
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
};
append_string_helper(e, type, d, customizer, callback);
}
private static void append_string_helper(CodeEmitter e,
Type type,
ArrayDelimiters delims,
Customizer customizer,
ProcessArrayCallback callback) {
Label skip = e.make_label();
Label end = e.make_label();
if (TypeUtils.isPrimitive(type)) {
switch (type.getSort()) {
case Type.INT:
case Type.SHORT:
case Type.BYTE:
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_INT);
break;
case Type.DOUBLE:
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_DOUBLE);
break;
case Type.FLOAT:
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_FLOAT);
break;
case Type.LONG:
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_LONG);
break;
case Type.BOOLEAN:
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_BOOLEAN);
break;
case Type.CHAR:
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_CHAR);
break;
}
} else if (TypeUtils.isArray(type)) {
e.dup();
e.ifnull(skip);
e.swap();
if (delims != null && delims.before != null && !"".equals(delims.before)) {
e.push(delims.before);
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
e.swap();
}
EmitUtils.process_array(e, type, callback);
shrinkStringBuffer(e, 2);
if (delims != null && delims.after != null && !"".equals(delims.after)) {
e.push(delims.after);
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
} else {
e.dup();
e.ifnull(skip);
if (customizer != null) {
customizer.customize(e, type);
}
e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING);
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
e.goTo(end);
e.mark(skip);
e.pop();
e.push("null");
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
e.mark(end);
}
private static void shrinkStringBuffer(CodeEmitter e, int amt) {
e.dup();
e.dup();
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, LENGTH);
e.push(amt);
e.math(e.SUB, Type.INT_TYPE);
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, SET_LENGTH);
}
public static class ArrayDelimiters {
private String before;
private String inside;
private String after;
public ArrayDelimiters(String before, String inside, String after) {
this.before = before;
this.inside = inside;
this.after = after;
}
}
public static void load_method(CodeEmitter e, MethodInfo method) {
load_class(e, method.getClassInfo().getType());
e.push(method.getSignature().getName());
push_object(e, method.getSignature().getArgumentTypes());
e.invoke_virtual(Constants.TYPE_CLASS, GET_DECLARED_METHOD);
}
private interface ParameterTyper {
Type[] getParameterTypes(MethodInfo member);
}
public static void method_switch(CodeEmitter e,
List methods,
ObjectSwitchCallback callback) {
member_switch_helper(e, methods, callback, true);
}
public static void constructor_switch(CodeEmitter e,
List constructors,
ObjectSwitchCallback callback) {
member_switch_helper(e, constructors, callback, false);
}
private static void member_switch_helper(final CodeEmitter e,
List members,
final ObjectSwitchCallback callback,
boolean useName) {
try {
final Map cache = new HashMap();
final ParameterTyper cached = new ParameterTyper() {
public Type[] getParameterTypes(MethodInfo 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() {
public Object transform(Object value) {
return ((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() {
public void processCase(Object key, Label dontUseEnd) throws Exception {
member_helper_size(e, (List)buckets.get(key), callback, cached, def, end);
}
public void processDefault() throws Exception {
e.goTo(def);
}
});
} else {
member_helper_size(e, members, callback, cached, def, end);
}
e.mark(def);
e.pop();
callback.processDefault();
e.mark(end);
} catch (RuntimeException ex) {
throw ex;
} catch (Error ex) {
throw ex;
} catch (Exception ex) {
throw new CodeGenerationException(ex);
}
}
private static void member_helper_size(final CodeEmitter e,
List members,
final ObjectSwitchCallback callback,
final ParameterTyper typer,
final Label def,
final Label end) throws Exception {
final Map buckets = CollectionUtils.bucket(members, new Transformer() {
public Object transform(Object value) {
return new Integer(typer.getParameterTypes((MethodInfo)value).length);
}
});
e.dup();
e.arraylength();
e.process_switch(EmitUtils.getSwitchKeys(buckets), new ProcessSwitchCallback() {
public void processCase(int key, Label dontUseEnd) throws Exception {
List bucket = (List)buckets.get(new Integer(key));
member_helper_type(e, bucket, callback, typer, def, end, new BitSet());
}
public void processDefault() throws Exception {
e.goTo(def);
}
});
}
private static void member_helper_type(final CodeEmitter e,
List members,
final ObjectSwitchCallback callback,
final ParameterTyper typer,
final Label def,
final Label end,
final BitSet checked) throws Exception {
if (members.size() == 1) {
MethodInfo member = (MethodInfo)members.get(0);
Type[] types = typer.getParameterTypes(member);
// need to check classes that have not already been checked via switches
for (int i = 0; i < types.length; i++) {
if (checked == null || !checked.get(i)) {
e.dup();
e.aaload(i);
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
e.push(TypeUtils.emulateClassGetName(types[i]));
e.invoke_virtual(Constants.TYPE_OBJECT, EQUALS);
e.if_jump(e.EQ, def);
}
}
e.pop();
callback.processCase(member, end);
} else {
// choose the index that has the best chance of uniquely identifying member
Type[] example = typer.getParameterTypes((MethodInfo)members.get(0));
Map buckets = null;
int index = -1;
for (int i = 0; i < example.length; i++) {
final int j = i;
Map test = CollectionUtils.bucket(members, new Transformer() {
public Object transform(Object value) {
return TypeUtils.emulateClassGetName(typer.getParameterTypes((MethodInfo)value)[j]);
}
});
if (buckets == null || test.size() > buckets.size()) {
buckets = test;
index = i;
}
}
if (buckets == null || buckets.size() == 1) {
// TODO: switch by returnType
// must have two methods with same name, types, and different return types
e.goTo(def);
} else {
checked.set(index);
e.dup();
e.aaload(index);
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
final Map fbuckets = buckets;
String[] names = (String[])buckets.keySet().toArray(new String[buckets.size()]);
EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
public void processCase(Object key, Label dontUseEnd) throws Exception {
member_helper_type(e, (List)fbuckets.get(key), callback, typer, def, end, checked);
}
public void processDefault() throws Exception {
e.goTo(def);
}
});
}
}
}
public static void wrap_throwable(Block block, Type wrapper) {
CodeEmitter e = block.getCodeEmitter();
e.catch_exception(block, Constants.TYPE_THROWABLE);
e.new_instance(wrapper);
e.dup_x1();
e.swap();
e.invoke_constructor(wrapper, CSTRUCT_THROWABLE);
e.athrow();
}
public static void add_properties(ClassEmitter ce, String[] names, Type[] types) {
for (int i = 0; i < names.length; i++) {
String fieldName = "$cglib_prop_" + names[i];
ce.declare_field(Constants.ACC_PRIVATE, fieldName, types[i], null);
EmitUtils.add_property(ce, names[i], types[i], fieldName);
}
}
public static void add_property(ClassEmitter ce, String name, Type type, String fieldName) {
String property = TypeUtils.upperFirst(name);
CodeEmitter e;
e = ce.begin_method(Constants.ACC_PUBLIC,
new Signature("get" + property,
type,
Constants.TYPES_EMPTY),
null);
e.load_this();
e.getfield(fieldName);
e.return_value();
e.end_method();
e = ce.begin_method(Constants.ACC_PUBLIC,
new Signature("set" + property,
Type.VOID_TYPE,
new Type[]{ type }),
null);
e.load_this();
e.load_arg(0);
e.putfield(fieldName);
e.return_value();
e.end_method();
}
/* generates:
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (equals
and hashCode
methods follow the
* the rules laid out in Effective Java by Joshua Bloch.
* KeyFactory
, you need to supply an interface which
* describes the structure of the key. The interface should have a
* single method named newInstance
, which returns an
* Object
. The arguments array can be
* anything--Objects, primitive values, or single or
* multi-dimension arrays of either. For example:
*
* private interface IntStringKey {
* public Object newInstance(int i, String s);
* }
*
KeyFactory
, you generate a new key by calling
* the newInstance
method defined by your interface.
*
* IntStringKey factory = (IntStringKey)KeyFactory.create(IntStringKey.class);
* Object key1 = factory.newInstance(4, "Hello");
* Object key2 = factory.newInstance(4, "World");
*
hashCode
equality between two keys key1
and key2
is only guaranteed if
* key1.equals(key2)
and the keys were produced by the same factory.
*
* @version $Id: KeyFactory.java,v 1.26 2006/03/05 02:43:19 herbyderby Exp $
*/
abstract public class KeyFactory {
private static final Signature GET_NAME =
TypeUtils.parseSignature("String getName()");
private static final Signature GET_CLASS =
TypeUtils.parseSignature("Class getClass()");
private static final Signature HASH_CODE =
TypeUtils.parseSignature("int hashCode()");
private static final Signature EQUALS =
TypeUtils.parseSignature("boolean equals(Object)");
private static final Signature TO_STRING =
TypeUtils.parseSignature("String toString()");
private static final Signature APPEND_STRING =
TypeUtils.parseSignature("StringBuffer append(String)");
private static final Type KEY_FACTORY =
TypeUtils.parseType("net.sf.cglib.core.KeyFactory");
//generated numbers:
private final static int PRIMES[] = {
11, 73, 179, 331,
521, 787, 1213, 1823,
2609, 3691, 5189, 7247,
10037, 13931, 19289, 26627,
36683, 50441, 69403, 95401,
131129, 180179, 247501, 340057,
467063, 641371, 880603, 1209107,
1660097, 2279161, 3129011, 4295723,
5897291, 8095873, 11114263, 15257791,
20946017, 28754629, 39474179, 54189869,
74391461, 102123817, 140194277, 192456917,
264202273, 362693231, 497900099, 683510293,
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 OBJECT_BY_CLASS = new Customizer() {
public void customize(CodeEmitter e, Type type) {
e.invoke_virtual(Constants.TYPE_OBJECT, GET_CLASS);
}
};
protected KeyFactory() {
}
public static KeyFactory create(Class keyInterface) {
return create(keyInterface, null);
}
public static KeyFactory create(Class keyInterface, Customizer customizer) {
return create(keyInterface.getClassLoader(), keyInterface, customizer);
}
public static KeyFactory create(ClassLoader loader, Class keyInterface, Customizer customizer) {
Generator gen = new Generator();
gen.setInterface(keyInterface);
gen.setCustomizer(customizer);
gen.setClassLoader(loader);
return gen.create();
}
public static class Generator extends AbstractClassGenerator {
private static final Source SOURCE = new Source(KeyFactory.class.getName());
private Class keyInterface;
private Customizer customizer;
private int constant;
private int multiplier;
public Generator() {
super(SOURCE);
}
protected ClassLoader getDefaultClassLoader() {
return keyInterface.getClassLoader();
}
public void setCustomizer(Customizer customizer) {
this.customizer = customizer;
}
public void setInterface(Class keyInterface) {
this.keyInterface = keyInterface;
}
public KeyFactory create() {
setNamePrefix(keyInterface.getName());
return (KeyFactory)super.create(keyInterface.getName());
}
public void setHashConstant(int constant) {
this.constant = constant;
}
public void setHashMultiplier(int multiplier) {
this.multiplier = multiplier;
}
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type);
}
protected Object nextInstance(Object instance) {
return instance;
}
public void generateClass(ClassVisitor v) {
ClassEmitter ce = new ClassEmitter(v);
Method newInstance = ReflectUtils.findNewInstance(keyInterface);
if (!newInstance.getReturnType().equals(Object.class)) {
throw new IllegalArgumentException("newInstance method must return Object");
}
Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
KEY_FACTORY,
new Type[]{ Type.getType(keyInterface) },
Constants.SOURCE_FILE);
EmitUtils.null_constructor(ce);
EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));
int seed = 0;
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
TypeUtils.parseConstructor(parameterTypes),
null);
e.load_this();
e.super_invoke_constructor();
e.load_this();
for (int i = 0; i < parameterTypes.length; i++) {
seed += parameterTypes[i].hashCode();
ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
getFieldName(i),
parameterTypes[i],
null);
e.dup();
e.load_arg(i);
e.putfield(getFieldName(i));
}
e.return_value();
e.end_method();
// hash code
e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
int hc = (constant != 0) ? constant : PRIMES[(int)(Math.abs(seed) % PRIMES.length)];
int hm = (multiplier != 0) ? multiplier : PRIMES[(int)(Math.abs(seed * 13) % PRIMES.length)];
e.push(hc);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.hash_code(e, parameterTypes[i], hm, customizer);
}
e.return_value();
e.end_method();
// equals
e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
Label fail = e.make_label();
e.load_arg(0);
e.instance_of_this();
e.if_jump(e.EQ, fail);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
e.load_arg(0);
e.checkcast_this();
e.getfield(getFieldName(i));
EmitUtils.not_equals(e, parameterTypes[i], fail, customizer);
}
e.push(1);
e.return_value();
e.mark(fail);
e.push(0);
e.return_value();
e.end_method();
// toString
e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
e.new_instance(Constants.TYPE_STRING_BUFFER);
e.dup();
e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
e.push(", ");
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizer);
}
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
e.return_value();
e.end_method();
ce.end_class();
}
private String getFieldName(int arg) {
return "FIELD_" + arg;
}
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ProcessSwitchCallback.java 0000644 0001750 0001750 00000001517 10066633132 025227 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Label;
public interface ProcessSwitchCallback {
void processCase(int key, Label end) throws Exception;
void processDefault() throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/DefaultNamingPolicy.java 0000644 0001750 0001750 00000004570 11132421266 024710 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.util.Set;
/**
* The default policy used by {@link AbstractClassGenerator}.
* Generates names such as
* net.sf.cglib.Foo$$EnhancerByCGLIB$$38272841
ClassLoader
, a
* suffix is added to ensure uniqueness.
*/
public class DefaultNamingPolicy implements NamingPolicy {
public static final DefaultNamingPolicy INSTANCE = new DefaultNamingPolicy();
public String getClassName(String prefix, String source, Object key, Predicate names) {
if (prefix == null) {
prefix = "net.sf.cglib.empty.Object";
} else if (prefix.startsWith("java")) {
prefix = "$" + prefix;
}
String base =
prefix + "$$" +
source.substring(source.lastIndexOf('.') + 1) +
getTag() + "$$" +
Integer.toHexString(key.hashCode());
String attempt = base;
int index = 2;
while (names.evaluate(attempt))
attempt = base + "_" + index++;
return attempt;
}
/**
* Returns a string which is incorporated into every generated class name.
* By default returns "ByCGLIB"
*/
protected String getTag() {
return "ByCGLIB";
}
public int hashCode() {
return getTag().hashCode();
}
public boolean equals(Object o) {
return (o instanceof DefaultNamingPolicy) && ((DefaultNamingPolicy) o).getTag().equals(getTag());
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ObjectSwitchCallback.java 0000644 0001750 0001750 00000001523 10066633132 025014 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Label;
public interface ObjectSwitchCallback {
void processCase(Object key, Label end) throws Exception;
void processDefault() throws Exception;
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/ClassesKey.java 0000644 0001750 0001750 00000001767 10066633132 023067 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
public class ClassesKey {
private static final Key FACTORY = (Key)KeyFactory.create(Key.class, KeyFactory.OBJECT_BY_CLASS);
interface Key {
Object newInstance(Object[] array);
}
private ClassesKey() {
}
public static Object create(Object[] array) {
return FACTORY.newInstance(array);
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/RejectModifierPredicate.java 0000644 0001750 0001750 00000001756 10066633132 025533 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.lang.reflect.*;
public class RejectModifierPredicate implements Predicate {
private int rejectMask;
public RejectModifierPredicate(int rejectMask) {
this.rejectMask = rejectMask;
}
public boolean evaluate(Object arg) {
return (((Member)arg).getModifiers() & rejectMask) == 0;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/Customizer.java 0000644 0001750 0001750 00000001411 10066633132 023147 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Type;
public interface Customizer {
void customize(CodeEmitter e, Type type);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/MethodInfo.java 0000644 0001750 0001750 00000002654 10402432050 023037 0 ustar miguel miguel /*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Type;
abstract public class MethodInfo {
protected MethodInfo() {
}
abstract public ClassInfo getClassInfo();
abstract public int getModifiers();
abstract public Signature getSignature();
abstract public Type[] getExceptionTypes();
public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof MethodInfo))
return false;
return getSignature().equals(((MethodInfo)o).getSignature());
}
public int hashCode() {
return getSignature().hashCode();
}
public String toString() {
// TODO: include modifiers, exceptions
return getSignature().toString();
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/MethodWrapper.java 0000644 0001750 0001750 00000003203 10251072654 023567 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.lang.reflect.Method;
import java.util.*;
public class MethodWrapper {
private static final MethodWrapperKey KEY_FACTORY =
(MethodWrapperKey)KeyFactory.create(MethodWrapperKey.class);
/** Internal interface, only public due to ClassLoader issues. */
public interface MethodWrapperKey {
public Object newInstance(String name, String[] parameterTypes, String returnType);
}
private MethodWrapper() {
}
public static Object create(Method method) {
return KEY_FACTORY.newInstance(method.getName(),
ReflectUtils.getNames(method.getParameterTypes()),
method.getReturnType().getName());
}
public static Set createSet(Collection methods) {
Set set = new HashSet();
for (Iterator it = methods.iterator(); it.hasNext();) {
set.add(create((Method)it.next()));
}
return set;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/Predicate.java 0000644 0001750 0001750 00000001334 10066633132 022707 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
public interface Predicate {
boolean evaluate(Object arg);
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/CodeGenerationException.java 0000644 0001750 0001750 00000002105 10066633132 025551 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
/**
* @version $Id: CodeGenerationException.java,v 1.3 2004/06/24 21:15:21 herbyderby Exp $
*/
public class CodeGenerationException extends RuntimeException {
private Throwable cause;
public CodeGenerationException(Throwable cause) {
super(cause.getClass().getName() + "-->" + cause.getMessage());
this.cause = cause;
}
public Throwable getCause() {
return cause;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/CollectionUtils.java 0000644 0001750 0001750 00000004624 10066633132 024130 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.util.*;
import java.lang.reflect.Array;
/**
* @author Chris Nokleberg
* @version $Id: CollectionUtils.java,v 1.7 2004/06/24 21:15:21 herbyderby Exp $
*/
public class CollectionUtils {
private CollectionUtils() { }
public static Map bucket(Collection c, Transformer t) {
Map buckets = new HashMap();
for (Iterator it = c.iterator(); it.hasNext();) {
Object value = (Object)it.next();
Object key = t.transform(value);
List bucket = (List)buckets.get(key);
if (bucket == null) {
buckets.put(key, bucket = new LinkedList());
}
bucket.add(value);
}
return buckets;
}
public static void reverse(Map source, Map target) {
for (Iterator it = source.keySet().iterator(); it.hasNext();) {
Object key = it.next();
target.put(source.get(key), key);
}
}
public static Collection filter(Collection c, Predicate p) {
Iterator it = c.iterator();
while (it.hasNext()) {
if (!p.evaluate(it.next())) {
it.remove();
}
}
return c;
}
public static List transform(Collection c, Transformer t) {
List result = new ArrayList(c.size());
for (Iterator it = c.iterator(); it.hasNext();) {
result.add(t.transform(it.next()));
}
return result;
}
public static Map getIndexMap(List list) {
Map indexes = new HashMap();
int index = 0;
for (Iterator it = list.iterator(); it.hasNext();) {
indexes.put(it.next(), new Integer(index++));
}
return indexes;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/Block.java 0000644 0001750 0001750 00000002356 10066633132 022046 0 ustar miguel miguel /*
* Copyright 2003 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import org.objectweb.asm.Label;
public class Block
{
private CodeEmitter e;
private Label start;
private Label end;
public Block(CodeEmitter e) {
this.e = e;
start = e.mark();
}
public CodeEmitter getCodeEmitter() {
return e;
}
public void end() {
if (end != null) {
throw new IllegalStateException("end of label already set");
}
end = e.mark();
}
public Label getStart() {
return start;
}
public Label getEnd() {
return end;
}
}
cglib3-3.1+dfsg/src/proxy/net/sf/cglib/core/TypeUtils.java 0000644 0001750 0001750 00000032027 12250620376 022757 0 ustar miguel miguel /*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.cglib.core;
import java.util.*;
import org.objectweb.asm.Type;
public class TypeUtils {
private static final Map transforms = new HashMap();
private static final Map rtransforms = new HashMap();
private TypeUtils() {
}
static {
transforms.put("void", "V");
transforms.put("byte", "B");
transforms.put("char", "C");
transforms.put("double", "D");
transforms.put("float", "F");
transforms.put("int", "I");
transforms.put("long", "J");
transforms.put("short", "S");
transforms.put("boolean", "Z");
CollectionUtils.reverse(transforms, rtransforms);
}
public static Type getType(String className) {
return Type.getType("L" + className.replace('.', '/') + ";");
}
public static boolean isFinal(int access) {
return (Constants.ACC_FINAL & access) != 0;
}
public static boolean isStatic(int access) {
return (Constants.ACC_STATIC & access) != 0;
}
public static boolean isProtected(int access) {
return (Constants.ACC_PROTECTED & access) != 0;
}
public static boolean isPublic(int access) {
return (Constants.ACC_PUBLIC & access) != 0;
}
public static boolean isAbstract(int access) {
return (Constants.ACC_ABSTRACT & access) != 0;
}
public static boolean isInterface(int access) {
return (Constants.ACC_INTERFACE & access) != 0;
}
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));
}
public static String getPackageName(String className) {
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;
}
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
public static String getClassName(Type type) {
if (isPrimitive(type)) {
return (String)rtransforms.get(type.getDescriptor());
} else if (isArray(type)) {
return getClassName(getComponentType(type)) + "[]";
} else {
return type.getClassName();
}
}
public static Type[] add(Type[] types, Type extra) {
if (types == null) {
return new Type[]{ extra };
} else {
List list = Arrays.asList(types);
if (list.contains(extra)) {
return types;
}
Type[] copy = new Type[types.length + 1];
System.arraycopy(types, 0, copy, 0, types.length);
copy[types.length] = extra;
return copy;
}
}
public static Type[] add(Type[] t1, Type[] t2) {
// TODO: set semantics?
Type[] all = new Type[t1.length + t2.length];
System.arraycopy(t1, 0, all, 0, t1.length);
System.arraycopy(t2, 0, all, t1.length, t2.length);
return all;
}
public static Type fromInternalName(String name) {
// TODO; primitives?
return Type.getType("L" + name + ";");
}
public static Type[] fromInternalNames(String[] names) {
if (names == null) {
return null;
}
Type[] types = new Type[names.length];
for (int i = 0; i < names.length; i++) {
types[i] = fromInternalName(names[i]);
}
return types;
}
public static int getStackSize(Type[] types) {
int size = 0;
for (int i = 0; i < types.length; i++) {
size += types[i].getSize();
}
return size;
}
public static String[] toInternalNames(Type[] types) {
if (types == null) {
return null;
}
String[] names = new String[types.length];
for (int i = 0; i < types.length; i++) {
names[i] = types[i].getInternalName();
}
return names;
}
public static Signature parseSignature(String s) {
int space = s.indexOf(' ');
int lparen = s.indexOf('(', space);
int rparen = s.indexOf(')', lparen);
String returnType = s.substring(0, space);
String methodName = s.substring(space + 1, lparen);
StringBuffer sb = new StringBuffer();
sb.append('(');
for (Iterator it = parseTypes(s, lparen + 1, rparen).iterator(); it.hasNext();) {
sb.append(it.next());
}
sb.append(')');
sb.append(map(returnType));
return new Signature(methodName, sb.toString());
}
public static Type parseType(String s) {
return Type.getType(map(s));
}
public static Type[] parseTypes(String s) {
List names = parseTypes(s, 0, s.length());
Type[] types = new Type[names.size()];
for (int i = 0; i < types.length; i++) {
types[i] = Type.getType((String)names.get(i));
}
return types;
}
public static Signature parseConstructor(Type[] types) {
StringBuffer sb = new StringBuffer();
sb.append("(");
for (int i = 0; i < types.length; i++) {
sb.append(types[i].getDescriptor());
}
sb.append(")");
sb.append("V");
return new Signature(Constants.CONSTRUCTOR_NAME, sb.toString());
}
public static Signature parseConstructor(String sig) {
return parseSignature("void