Package com.thoughtworks.proxy.toys.decorate

A toy to decorate the interaction with another object.

See:
          Description

Class Summary
Decorating<U,T> Toy factory to create proxies decorating an object in an AOP style.
Decorating.DecoratingBuild<U,T>  
Decorating.DecoratingVisitor<U,T>  
Decorating.DecoratingWith<T>  
DecoratingInvoker<T> Invoker implementation for the decorating proxy.
Decorator<T> Identity implementation for a Decorator.
 

Package com.thoughtworks.proxy.toys.decorate Description

A toy to decorate the interaction with another object.

The package provides a proxy factory creating proxies, that are used to decorate the interaction with another object as done with AOP. Main component is the Decorating toy, a utility class creating these proxies. Such a proxy contains an instance of a DecoratingInvoker that defines the additional functionality. A DecoratingInvoker is invoked for each method call on the proxy, for each value returned from a proxied method, for each exception thrown from the original object's method and for each occurring exception invoking the method in the original object.

The following example decorates an iterator of a list of strings to convert every String into an Integer. This is obviously not a type safe operation, therefore all warnings for using unchecked types are suppressed:

List<String> list = Arrays.asList("1", "2", "3");
@SuppressWarnings({"serial", "unchecked"})
Decorator<Iterator> decorator = new Decorator<Iterator>() {
    @Override
    public Object decorateResult(Iterator proxy, Method method, Object[] args, Object result) {
        if (method.getName().equals("next"))
            return Integer.valueOf(String.class.cast(result));
        else
            return result;
    }
};
@SuppressWarnings("unchecked")
Iterator<Integer> intIter = Decorating.proxy(Iterator.class)
    .with(list.iterator())
    .visiting(decorator)
    .build();
while (intIter.hasNext()) {
    Integer i = intIter.next();
    System.out.println(i);
}

The next example implements a simple trace mechanism for a single object. Since we proxy here a real object instead of an interface, we have to use the CglibProxyFactory:

File file = new File(".");
@SuppressWarnings("serial")
Decorator decorator = new Decorator() {
    @Override
    public Object[] beforeMethodStarts(Object proxy, Method method, Object[] args) {
        System.out.print("Called: " + method.getName());
        return super.beforeMethodStarts(proxy, method, args);
    }
    @Override
    public Object decorateResult(Object proxy, Method method, Object[] args, Object result) {
        System.out.println(" ==< " + result);
        return result;
    }
};
File decoratedFile = Decorating.proxy(File.class)
    .with(file, decorator)
    .build(new CglibProxyFactory());
decoratedFile.exists();
decoratedFile.isFile();
decoratedFile.isDirectory();

For a more sophisticated trace mechanism, have a look at the Echoing toy



Copyright © 2005-2010 Codehaus. All Rights Reserved.