001 /*
002 * (c) 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 19-03-2010.
010 */
011 package com.thoughtworks.proxy.toys.privilege;
012
013 import com.thoughtworks.proxy.ProxyFactory;
014 import com.thoughtworks.proxy.factory.StandardProxyFactory;
015 import com.thoughtworks.proxy.kit.SimpleReference;
016
017 /**
018 * Toy factory to create proxies executing the method calls as privileged actions.
019 *
020 * @author Jörg Schaible
021 * @see com.thoughtworks.proxy.toys.privilege
022 * @since 1.0
023 */
024 public class Privileging<T>
025 {
026 private Class<T> type;
027 private Object delegate;
028 private ActionExecutor executor;
029
030 /**
031 * Creates a factory for proxy instances that allow a privileged execution of the methods of an object.
032 *
033 * @param type the type of the proxy when it is finally created.
034 * @return a factory that will proxy instances of the supplied type.
035 * @since 1.0
036 */
037 public static <T> PrivilegingWith<T> proxy(Class<T> type) {
038 return new PrivilegingWith<T>(new Privileging<T>(type));
039 }
040
041 /**
042 * Creates a factory for proxy instances that allow a privileged execution of the methods of an object.
043 *
044 * @param target the target object that is proxied.
045 * @return a factory that will proxy instances of the supplied type.
046 * @since 1.0
047 */
048 public static <T> PrivilegingExecutedByOrBuild<T> proxy(T target) {
049 @SuppressWarnings("unchecked")
050 Class<T> type = (Class<T>)target.getClass();
051 Privileging<T> privileging = new Privileging<T>(type);
052 privileging.delegate = target;
053 return new PrivilegingExecutedByOrBuild<T>(privileging);
054 }
055
056 private Privileging(Class<T> type) {
057 this.type = type;
058 }
059
060 public static class PrivilegingWith<T> {
061 private Privileging<T> delegating;
062
063 private PrivilegingWith(Privileging<T> delegating) {
064 this.delegating = delegating;
065 }
066
067 /**
068 * With this delegate.
069 *
070 * @param delegate the object the proxy delegates to.
071 * @return the factory that will route calls to the supplied delegate.
072 * @since 1.0
073 */
074 public PrivilegingExecutedByOrBuild<T> with(Object delegate) {
075 delegating.delegate = delegate;
076 return new PrivilegingExecutedByOrBuild<T>(delegating);
077 }
078 }
079
080 public static class PrivilegingExecutedByOrBuild<T> extends PrivilegingBuild<T>{
081 private PrivilegingExecutedByOrBuild(Privileging<T> privileging) {
082 super(privileging);
083 }
084
085 /**
086 * Executed with this action executor.
087 *
088 * @param executor the executor that runs the privileged actions.
089 * @return the factory that will route calls to the supplied delegate.
090 * @since 1.0
091 */
092 public PrivilegingBuild<T> executedBy(ActionExecutor executor) {
093 privileging.executor = executor;
094 return new PrivilegingBuild<T>(privileging);
095 }
096 }
097
098 public static class PrivilegingBuild<T> {
099 protected Privileging<T> privileging;
100
101 private PrivilegingBuild(Privileging<T> privileging) {
102 this.privileging = privileging;
103 }
104
105 /**
106 * Creating a privileging proxy for an object using the {@link StandardProxyFactory}.
107 *
108 * @return the created proxy implementing the <tt>type</tt>
109 * @since 1.0
110 */
111 public T build() {
112 return build(new StandardProxyFactory());
113 }
114
115 /**
116 * Creating a privileging proxy for an object using a special {@link ProxyFactory}.
117 *
118 * @param factory the {@link ProxyFactory} to use.
119 * @return the created proxy implementing the <tt>type</tt>
120 * @since 1.0
121 */
122 public T build(ProxyFactory factory) {
123 return factory.<T>createProxy(new PrivilegingInvoker<Object>(factory,
124 new SimpleReference<Object>(privileging.delegate), privileging.executor), privileging.type);
125 }
126 }
127 }