001 /* 002 * (c) 2003-2005, 2009, 2010 ThoughtWorks Ltd 003 * All rights reserved. 004 * 005 * The software in this package is published under the terms of the BSD 006 * style license a copy of which has been included with this distribution in 007 * the LICENSE.txt file. 008 * 009 * Created on 04-Feb-2004 010 */ 011 package com.thoughtworks.proxy.toys.echo; 012 013 import java.io.PrintWriter; 014 015 import com.thoughtworks.proxy.ProxyFactory; 016 import com.thoughtworks.proxy.factory.StandardProxyFactory; 017 import com.thoughtworks.proxy.toys.decorate.Decorating; 018 019 /** 020 * Factory for echoing proxy instances. 021 * <p> 022 * The Echoing toy acts as a decorator where every method invocation is written to a PrintWriter first. 023 * </p> 024 * 025 * @author Dan North 026 * @author Jörg Schaible 027 * @author Juan Li 028 * @author Paul Hammant 029 * @see com.thoughtworks.proxy.toys.echo 030 * @since 0.1 031 */ 032 public class Echoing<T> { 033 034 private Class<T> type; 035 private Object delegate; 036 private PrintWriter printWriter = new PrintWriter(System.err); 037 038 private Echoing(final Class<T> type) { 039 this.type = type; 040 } 041 042 /** 043 * Creates a factory for proxy instances that allow delegation. 044 * 045 * @param type the type of the proxy when it is finally created. 046 * @return a factory that will proxy instances of the supplied type. 047 * @since 1.0 048 */ 049 public static <T> EchoingWithOrTo<T> proxy(final Class<T> type) { 050 return new EchoingWithOrTo<T>(new Echoing<T>(type)); 051 } 052 053 public static class EchoingWithOrTo<T> extends EchoingTo<T> { 054 055 private EchoingWithOrTo(Echoing<T> echoing) { 056 super(echoing); 057 } 058 059 /** 060 * Specify the delegate. 061 * 062 * @param delegate the object the proxy delegates to. 063 * @return the factory that will proxy instances of the supplied type. 064 * @since 1.0 065 */ 066 public EchoingTo<T> with(final Object delegate) { 067 echoing.delegate = delegate; 068 return new EchoingTo<T>(echoing); 069 } 070 071 } 072 073 public static class EchoingTo<T> { 074 protected Echoing<T> echoing; 075 076 private EchoingTo(Echoing<T> echoing) { 077 this.echoing = echoing; 078 } 079 080 /** 081 * Specify the printWriter. 082 * 083 * @param printWriter which receives the output 084 * @return the factory that will proxy instances of the supplied type. 085 * @since 1.0 086 */ 087 public EchoingBuild<T> to(final PrintWriter printWriter) { 088 echoing.printWriter = printWriter; 089 return new EchoingBuild<T>(echoing); 090 } 091 092 } 093 094 public static class EchoingBuild<T> { 095 private Echoing<T> echoing; 096 097 private EchoingBuild(Echoing<T> echoing) { 098 this.echoing = echoing; 099 } 100 101 102 /** 103 * Creating a delegating proxy for an object using the {@link StandardProxyFactory}. 104 * 105 * @return the created proxy implementing the <tt>type</tt> 106 * @since 1.0 107 */ 108 public T build() { 109 return build(new StandardProxyFactory()); 110 } 111 112 /** 113 * Creating a delegating proxy for an object using a special {@link ProxyFactory}. 114 * 115 * @param proxyFactory the {@link ProxyFactory} to use. 116 * @return the created proxy implementing the <tt>type</tt> 117 * @since 1.0 118 */ 119 public T build(final ProxyFactory proxyFactory) { 120 EchoDecorator<T> decorator = new EchoDecorator<T>(echoing.printWriter, proxyFactory); 121 return Decorating.proxy(echoing.delegate, echoing.type).visiting(decorator).build(proxyFactory); 122 } 123 } 124 }