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 }