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 }