/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.extender.internal.util; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; /** * Utility class for commons actions used within PrivilegedBlocks. * * @author Costin Leau * */ public abstract class PrivilegedUtils { private static class GetTCCLAction implements PrivilegedAction<ClassLoader> { public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); } public ClassLoader getTCCL() { return AccessController.doPrivileged(this); } } public interface UnprivilegedThrowableExecution<T> { public T run() throws Throwable; } public interface UnprivilegedExecution<T> { public T run(); } private static final GetTCCLAction getTCCLAction = new GetTCCLAction(); public static ClassLoader getTCCL() { return getTCCLAction.getTCCL(); } /** * Temporarily changes the TCCL to the given one for the duration of the * given execution. All actions except the execution are executed with * privileged access. * * Consider checking if there is a security manager in place before calling * this method. * * @param customClassLoader * @param execution * @return */ public static <T> T executeWithCustomTCCL(final ClassLoader customClassLoader, final UnprivilegedExecution<T> execution) { final Thread currentThread = Thread.currentThread(); final ClassLoader oldTCCL = getTCCLAction.getTCCL(); try { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { currentThread.setContextClassLoader(customClassLoader); return null; } }); return execution.run(); } finally { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { currentThread.setContextClassLoader(oldTCCL); return null; } }); } } /** * Temporarily changes the TCCL to the given one for the duration of the * given execution. All actions except the execution are executed with * privileged access. * * Consider checking if there is a security manager in place before calling * this method. * * @param customClassLoader * @param execution * @return * @throws Throwable */ public static <T> T executeWithCustomTCCL(final ClassLoader customClassLoader, final UnprivilegedThrowableExecution<T> execution) throws Throwable { final Thread currentThread = Thread.currentThread(); final ClassLoader oldTCCL = getTCCLAction.getTCCL(); try { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { currentThread.setContextClassLoader(customClassLoader); return null; } }); return execution.run(); } catch (PrivilegedActionException pae) { throw pae.getCause(); } finally { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { currentThread.setContextClassLoader(oldTCCL); return null; } }); } } }