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 java.lang.reflect.InvocationTargetException;
014 import java.lang.reflect.Method;
015 import java.security.PrivilegedActionException;
016 import java.security.PrivilegedExceptionAction;
017
018 import com.thoughtworks.proxy.ProxyFactory;
019 import com.thoughtworks.proxy.factory.StandardProxyFactory;
020 import com.thoughtworks.proxy.kit.ObjectReference;
021 import com.thoughtworks.proxy.kit.SimpleReference;
022 import com.thoughtworks.proxy.toys.delegate.DelegatingInvoker;
023 import com.thoughtworks.proxy.toys.delegate.DelegationMode;
024
025
026 /**
027 * {@link com.thoughtworks.proxy.Invoker Invoker} that creates for the invoked method a
028 * {@link PrivilegedExceptionAction} and runs this action with the provided
029 * {@link ActionExecutor}.
030 *
031 * @author Jörg Schaible
032 * @since 1.0
033 */
034 public class PrivilegingInvoker<T> extends DelegatingInvoker<T> {
035 private static final long serialVersionUID = 5352672950789740381L;
036 private final ActionExecutor executor;
037
038 /**
039 * Construct the invoker.
040 *
041 * @param proxyFactory the proxy factory used to create the proxy
042 * @param delegateReference the reference object managing the delegate for the call
043 * @param executor the executor of the {@link PrivilegedExceptionAction}
044 * @since 1.0
045 */
046 public PrivilegingInvoker(
047 ProxyFactory proxyFactory, ObjectReference<T> delegateReference, ActionExecutor executor) {
048 super(proxyFactory, delegateReference, DelegationMode.DIRECT);
049 this.executor = executor == null ? new AccessControllerExecutor() : executor;
050 }
051
052 /**
053 * Construct the invoker.
054 *
055 * @param delegate the delegate for the call
056 * @param executor the executor of the {@link PrivilegedExceptionAction}
057 * @since 1.0
058 */
059 public PrivilegingInvoker(T delegate, ActionExecutor executor) {
060 this(new StandardProxyFactory(), new SimpleReference<T>(delegate), executor);
061 }
062
063 /**
064 * Construct the invoker using a {@link AccessControllerExecutor}.
065 *
066 * @param delegate the delegate for the call
067 * @since 1.0
068 */
069 public PrivilegingInvoker(T delegate) {
070 this(delegate, null);
071 }
072
073 @Override
074 protected Object invokeOnDelegate(final Method method, final Object[] args)
075 throws InvocationTargetException {
076 try {
077 return executor.execute(new PrivilegedExceptionAction<Object>() {
078 public Object run() throws Exception {
079 return PrivilegingInvoker.super.invokeOnDelegate(method, args);
080 }
081 });
082 } catch (PrivilegedActionException e) {
083 final Throwable cause = e.getCause();
084 if (cause instanceof InvocationTargetException) {
085 throw InvocationTargetException.class.cast(cause);
086 } else {
087 throw new InvocationTargetException(cause);
088 }
089 }
090 }
091 }