Coverage Report - org.kuali.rice.core.impl.resourceloader.ContextClassLoaderProxy
 
Classes in this File Line Coverage Branch Coverage Complexity
ContextClassLoaderProxy
0%
0/29
0%
0/10
1.9
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.core.impl.resourceloader;
 17  
 
 18  
 import org.kuali.rice.core.api.util.ClassLoaderUtils;
 19  
 import org.kuali.rice.core.api.util.reflect.BaseTargetedInvocationHandler;
 20  
 
 21  
 import java.lang.reflect.InvocationTargetException;
 22  
 import java.lang.reflect.Method;
 23  
 import java.lang.reflect.Proxy;
 24  
 
 25  
 /**
 26  
  * A Proxy that sets the thread Context ClassLoader before invocation of the
 27  
  * proxied object, and resets it back afterwards.
 28  
  *
 29  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 30  
  */
 31  
 public class ContextClassLoaderProxy extends BaseTargetedInvocationHandler {
 32  
 
 33  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ContextClassLoaderProxy.class);
 34  
 
 35  
     /**
 36  
      * Convenience method that wraps a specified object with a ContextClassLoaderProxy, with a specified
 37  
      * handler classloader and proxy classloader.  If the specified object is null, or the object classloader
 38  
      * equals the proxy classloader, the object is returned unwrapped.
 39  
      * @param proxiedObject the object to proxy
 40  
      * @param proxyClassLoader the classloader OF THE PROXY INSTANCE
 41  
      * @param objectClassLoader the classloader to set as the context classloader prior to any invocations on the proxiedObject
 42  
      * @return a ContextClassLoaderProxy Proxy for the proxiedObject
 43  
      */
 44  
     public static Object wrap(Object proxiedObject, Class<?>[] classesToProxy, ClassLoader proxyClassLoader, ClassLoader objectClassLoader) {
 45  0
         if (proxiedObject == null) {
 46  0
                 return null;
 47  
         }
 48  0
             if (proxyClassLoader == null) {
 49  
             //proxyClassLoader = Thread.currentThread().getContextClassLoader();
 50  0
                 proxyClassLoader = proxiedObject.getClass().getClassLoader();
 51  
         }
 52  0
         if (objectClassLoader == null) {
 53  0
             objectClassLoader = proxiedObject.getClass().getClassLoader();
 54  
         }
 55  0
         if (classesToProxy == null) {
 56  0
             classesToProxy = getInterfacesToProxy(proxyClassLoader, proxiedObject);
 57  
         }
 58  
         // this classloader comparison looks fishy
 59  
         // it is testing the classloader of the proxy against the intended *context* classloader of the proxiedObject
 60  
         // if these are the same the proxiedObject is not wrapped.  However, that implies that if the proxy
 61  
         // classloader may equal the intended context class loader, that the context class loader is actually not set,
 62  
         // and could theoretically NOT be the intended one in the future
 63  
         // somebody who understands this better than me should investigate this, and this method which I have
 64  
         // now applied to all prior uses of ContextClassLoaderProxy as a convenience
 65  
         //if (proxiedObject != null) { //&& !objectClassLoader.equals(proxyClassLoader)) {
 66  0
         ContextClassLoaderProxy handler = new ContextClassLoaderProxy(objectClassLoader, proxiedObject);
 67  0
         LOG.debug("Installed a ContextClassLoaderProxy on object: " + proxiedObject.getClass().getName());
 68  0
         proxiedObject = Proxy.newProxyInstance(proxyClassLoader, classesToProxy, handler);
 69  
         //}
 70  
 
 71  0
         return proxiedObject;
 72  
     }
 73  
 
 74  
     public static Object wrap(Object proxiedObject, ClassLoader proxyClassLoader, ClassLoader objectClassLoader) {
 75  0
             return wrap(proxiedObject, null, proxyClassLoader, objectClassLoader);
 76  
     }
 77  
 
 78  
     public static Object wrap(Object proxiedObject, ClassLoader classLoader) {
 79  0
             return wrap(proxiedObject, classLoader, classLoader);
 80  
     }
 81  
 
 82  
     public static Object wrap(Object proxiedObject, Class<?>[] classesToProxy) {
 83  0
             return wrap(proxiedObject, classesToProxy, null, null);
 84  
     }
 85  
 
 86  
     public static Object wrap(Object proxiedObject, Class<?>[] classesToProxy, ClassLoader classLoader) {
 87  0
             return wrap(proxiedObject, classesToProxy, classLoader, classLoader);
 88  
     }
 89  
 
 90  
     public static Object wrap(Object proxiedObject) {
 91  0
             return wrap(proxiedObject, null, null, null);
 92  
     }
 93  
 
 94  
     public static Class<?>[] getInterfacesToProxy(Object proxiedObject) {
 95  0
         return getInterfacesToProxy(null, proxiedObject);
 96  
     }
 97  
 
 98  
     /**
 99  
      * Determines the interfaces which need to be proxied and are visable to the given proxy ClassLoader.
 100  
      */
 101  
     public static Class<?>[] getInterfacesToProxy(ClassLoader proxyClassLoader, Object proxiedObject) {
 102  0
             return ClassLoaderUtils.getInterfacesToProxy(proxiedObject, proxyClassLoader, null);
 103  
     }
 104  
 
 105  
     private ClassLoader classLoader;
 106  
 
 107  
     public ContextClassLoaderProxy(ClassLoader classLoader, Object target) {
 108  0
             super(target);
 109  0
         this.classLoader = classLoader;
 110  0
     }
 111  
 
 112  
     protected Object invokeInternal(Object proxy, Method m, Object[] args) throws Throwable {
 113  0
         ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
 114  
         try {
 115  0
             Thread.currentThread().setContextClassLoader(this.classLoader);
 116  0
             return m.invoke(getTarget(), args);
 117  0
         } catch (InvocationTargetException e) {
 118  0
                 throw (e.getCause() != null ? e.getCause() : e);
 119  
         } finally {
 120  0
             Thread.currentThread().setContextClassLoader(oldCl);
 121  
         }
 122  
     }
 123  
 }