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 2006-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  
 
 17  
 package org.kuali.rice.core.impl.resourceloader;
 18  
 
 19  
 import org.kuali.rice.core.api.util.ClassLoaderUtils;
 20  
 import org.kuali.rice.core.api.util.reflect.BaseTargetedInvocationHandler;
 21  
 
 22  
 import java.lang.reflect.InvocationTargetException;
 23  
 import java.lang.reflect.Method;
 24  
 import java.lang.reflect.Proxy;
 25  
 
 26  
 /**
 27  
  * A Proxy that sets the thread Context ClassLoader before invocation of the
 28  
  * proxied object, and resets it back afterwards.
 29  
  *
 30  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 31  
  */
 32  
 public class ContextClassLoaderProxy extends BaseTargetedInvocationHandler {
 33  
 
 34  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ContextClassLoaderProxy.class);
 35  
 
 36  
     /**
 37  
      * Convenience method that wraps a specified object with a ContextClassLoaderProxy, with a specified
 38  
      * handler classloader and proxy classloader.  If the specified object is null, or the object classloader
 39  
      * equals the proxy classloader, the object is returned unwrapped.
 40  
      * @param proxiedObject the object to proxy
 41  
      * @param proxyClassLoader the classloader OF THE PROXY INSTANCE
 42  
      * @param objectClassLoader the classloader to set as the context classloader prior to any invocations on the proxiedObject
 43  
      * @return a ContextClassLoaderProxy Proxy for the proxiedObject
 44  
      */
 45  
     public static Object wrap(Object proxiedObject, Class<?>[] classesToProxy, ClassLoader proxyClassLoader, ClassLoader objectClassLoader) {
 46  0
         if (proxiedObject == null) {
 47  0
                 return null;
 48  
         }
 49  0
             if (proxyClassLoader == null) {
 50  
             //proxyClassLoader = Thread.currentThread().getContextClassLoader();
 51  0
                 proxyClassLoader = proxiedObject.getClass().getClassLoader();
 52  
         }
 53  0
         if (objectClassLoader == null) {
 54  0
             objectClassLoader = proxiedObject.getClass().getClassLoader();
 55  
         }
 56  0
         if (classesToProxy == null) {
 57  0
             classesToProxy = getInterfacesToProxy(proxyClassLoader, proxiedObject);
 58  
         }
 59  
         // this classloader comparison looks fishy
 60  
         // it is testing the classloader of the proxy against the intended *context* classloader of the proxiedObject
 61  
         // if these are the same the proxiedObject is not wrapped.  However, that implies that if the proxy
 62  
         // classloader may equal the intended context class loader, that the context class loader is actually not set,
 63  
         // and could theoretically NOT be the intended one in the future
 64  
         // somebody who understands this better than me should investigate this, and this method which I have
 65  
         // now applied to all prior uses of ContextClassLoaderProxy as a convenience
 66  
         //if (proxiedObject != null) { //&& !objectClassLoader.equals(proxyClassLoader)) {
 67  0
         ContextClassLoaderProxy handler = new ContextClassLoaderProxy(objectClassLoader, proxiedObject);
 68  0
         LOG.debug("Installed a ContextClassLoaderProxy on object: " + proxiedObject.getClass().getName());
 69  0
         proxiedObject = Proxy.newProxyInstance(proxyClassLoader, classesToProxy, handler);
 70  
         //}
 71  
 
 72  0
         return proxiedObject;
 73  
     }
 74  
 
 75  
     public static Object wrap(Object proxiedObject, ClassLoader proxyClassLoader, ClassLoader objectClassLoader) {
 76  0
             return wrap(proxiedObject, null, proxyClassLoader, objectClassLoader);
 77  
     }
 78  
 
 79  
     public static Object wrap(Object proxiedObject, ClassLoader classLoader) {
 80  0
             return wrap(proxiedObject, classLoader, classLoader);
 81  
     }
 82  
 
 83  
     public static Object wrap(Object proxiedObject, Class<?>[] classesToProxy) {
 84  0
             return wrap(proxiedObject, classesToProxy, null, null);
 85  
     }
 86  
 
 87  
     public static Object wrap(Object proxiedObject, Class<?>[] classesToProxy, ClassLoader classLoader) {
 88  0
             return wrap(proxiedObject, classesToProxy, classLoader, classLoader);
 89  
     }
 90  
 
 91  
     public static Object wrap(Object proxiedObject) {
 92  0
             return wrap(proxiedObject, null, null, null);
 93  
     }
 94  
 
 95  
     public static Class<?>[] getInterfacesToProxy(Object proxiedObject) {
 96  0
         return getInterfacesToProxy(null, proxiedObject);
 97  
     }
 98  
 
 99  
     /**
 100  
      * Determines the interfaces which need to be proxied and are visable to the given proxy ClassLoader.
 101  
      */
 102  
     public static Class<?>[] getInterfacesToProxy(ClassLoader proxyClassLoader, Object proxiedObject) {
 103  0
             return ClassLoaderUtils.getInterfacesToProxy(proxiedObject, proxyClassLoader, null);
 104  
     }
 105  
 
 106  
     private ClassLoader classLoader;
 107  
 
 108  
     public ContextClassLoaderProxy(ClassLoader classLoader, Object target) {
 109  0
             super(target);
 110  0
         this.classLoader = classLoader;
 111  0
     }
 112  
 
 113  
     protected Object invokeInternal(Object proxy, Method m, Object[] args) throws Throwable {
 114  0
         ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
 115  
         try {
 116  0
             Thread.currentThread().setContextClassLoader(this.classLoader);
 117  0
             return m.invoke(getTarget(), args);
 118  0
         } catch (InvocationTargetException e) {
 119  0
                 throw (e.getCause() != null ? e.getCause() : e);
 120  
         } finally {
 121  0
             Thread.currentThread().setContextClassLoader(oldCl);
 122  
         }
 123  
     }
 124  
 }