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 {@linkplain com.thoughtworks.proxy.toys.decorate.Decorating Decorating toy}, a utility class creating these proxies. Such a proxy contains an instance of a {@link com.thoughtworks.proxy.toys.decorate.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 occuring 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:
List list = Arrays.asList(new String[]{"1", "2", "3"}); Iterator intIter = (Iterator)Decorating.object(Iterator.class, list.iterator(), new InvocationDecoratorSupport() { public Object decorateResult(Object proxy, Method method, Object[] args, Object result) { if (method.getName().equals("next")) return Integer.valueOf((String)result); else return result; } }); while(intIter.hasNext()) { Integer i = (Integer)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 {@link com.thoughtworks.proxy.factory.CglibProxyFactory}:
File file = new File("."); File decoratedFile = (File)Decorating.object(new Class[]{File.class}, file, new InvocationDecoratorSupport() { public Object[] beforeMethodStarts(Object proxy, Method method, Object[] args) { System.out.print("Called: " + method.getName()); return super.beforeMethodStarts(proxy, method, args); } public Object decorateResult(Object proxy, Method method, Object[] args, Object result) { System.out.println(" ==> " + result); return result; } }, new CglibProxyFactory()); decoratedFile.exists(); decoratedFile.isFile(); decoratedFile.isDirectory();
For a more sophisticated trace mechanism, have a look at the {@linkplain com.thoughtworks.proxy.toys.echo Echoing toy}