package org.oddjob.framework;
import junit.framework.TestCase;
public class ProxyGeneratorTest extends TestCase {
// The component implements this.
interface Fruit {
String getType();
}
class Apple implements Fruit {
@Override
public String getType() {
return "apple";
}
}
// We proxy this.
interface Snack {
public void eat();
}
// Invocations for Snack
class FruitWrapper implements ComponentWrapper, Snack {
final Fruit fruit;
int eaten;
String type;
public FruitWrapper(Fruit fruit) {
this.fruit = fruit;
}
@Override
public void eat() {
++eaten;
type = fruit.getType();
}
}
public void testGenerate() {
ProxyGenerator<Fruit> test = new ProxyGenerator<Fruit>();
final Fruit fruit = new Apple();
final FruitWrapper wrapper = new FruitWrapper(fruit);
Object proxy = test.generate(fruit,
new WrapperFactory<ProxyGeneratorTest.Fruit>() {
@Override
public Class<?>[] wrappingInterfacesFor(Fruit wrapped) {
return new Class[] { Snack.class };
}
@Override
public ComponentWrapper wrapperFor(Fruit wrapped,
Object proxy) {
return wrapper;
}
}, getClass().getClassLoader());
assertTrue(proxy instanceof Fruit);
assertTrue(proxy instanceof Snack);
assertEquals("apple", ((Fruit) proxy).getType());
((Snack) proxy).eat();
assertEquals(1, wrapper.eaten);
assertEquals("apple", wrapper.type);
}
interface Vegetable {
String getColour();
}
class Tomato implements Vegetable {
@Override
public String getColour() {
return "red";
}
}
class VegetableAdaptor implements Fruit, ComponentAdapter {
final Vegetable vegetable;
public VegetableAdaptor(Vegetable vegetable) {
this.vegetable = vegetable;
}
@Override
public String getType() {
return vegetable.getClass().getSimpleName();
}
@Override
public Object getComponent() {
return vegetable;
}
}
public void testGenerateAdaptor() {
ProxyGenerator<Fruit> test = new ProxyGenerator<Fruit>();
final Fruit fruit = new VegetableAdaptor(new Tomato());
final FruitWrapper wrapper = new FruitWrapper(fruit);
Object proxy = test.generate(fruit,
new WrapperFactory<ProxyGeneratorTest.Fruit>() {
@Override
public Class<?>[] wrappingInterfacesFor(Fruit wrapped) {
return new Class[] { Snack.class };
}
@Override
public ComponentWrapper wrapperFor(Fruit wrapped,
Object proxy) {
return wrapper;
}
}, getClass().getClassLoader());
assertTrue(proxy instanceof Vegetable);
assertTrue(proxy instanceof Snack);
assertEquals("red", ((Vegetable) proxy).getColour());
((Snack) proxy).eat();
assertEquals(1, wrapper.eaten);
assertEquals("Tomato", wrapper.type);
}
}