/******************************************************************************
* Copyright (c) 2006, 2010 VMware Inc., Oracle 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.
* Oracle Inc.
*****************************************************************************/
package org.eclipse.gemini.blueprint.service.util.internal.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils;
import org.springframework.util.ObjectUtils;
/**
* Simple interceptor for dealing with ThreadContextClassLoader(TCCL)
* management.
*
* @author Hal Hildebrand
* @author Costin Leau
*/
public class ServiceTCCLInterceptor implements MethodInterceptor {
private static final int hashCode = ServiceTCCLInterceptor.class.hashCode() * 13;
/** classloader to set the TCCL during invocation */
private final ClassLoader loader;
/**
* Constructs a new <code>OsgiServiceTCCLInterceptor</code> instance.
*
* @param loader classloader to use for TCCL during invocation. Can be null.
*/
public ServiceTCCLInterceptor(ClassLoader loader) {
this.loader = loader;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
if (System.getSecurityManager() != null) {
return invokePrivileged(invocation);
}
else {
return invokeUnprivileged(invocation);
}
}
private Object invokePrivileged(final MethodInvocation invocation) throws Throwable {
return PrivilegedUtils.executeWithCustomTCCL(loader, new PrivilegedUtils.UnprivilegedThrowableExecution() {
public Object run() throws Throwable {
return invocation.proceed();
}
});
}
private Object invokeUnprivileged(MethodInvocation invocation) throws Throwable {
ClassLoader previous = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(loader);
return invocation.proceed();
}
finally {
Thread.currentThread().setContextClassLoader(previous);
}
}
public boolean equals(Object other) {
if (this == other)
return true;
if (other instanceof ServiceTCCLInterceptor) {
ServiceTCCLInterceptor oth = (ServiceTCCLInterceptor) other;
return (ObjectUtils.nullSafeEquals(loader, oth.loader));
}
return false;
}
public int hashCode() {
return hashCode;
}
}