Coverage Report - org.apache.ojb.broker.core.proxy.ProxyFactoryJDKImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ProxyFactoryJDKImpl
N/A
N/A
1.75
 
 1  
 package org.apache.ojb.broker.core.proxy;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
 *
 5  
 * Licensed under the Apache License, Version 2.0 (the "License");
 6  
 * you may not use this file except in compliance with the License.
 7  
 * You may obtain a copy of the License at
 8  
 *
 9  
 *     http://www.apache.org/licenses/LICENSE-2.0
 10  
 *
 11  
 * Unless required by applicable law or agreed to in writing, software
 12  
 * distributed under the License is distributed on an "AS IS" BASIS,
 13  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
 * See the License for the specific language governing permissions and
 15  
 * limitations under the License.
 16  
 */
 17  
 
 18  
 
 19  
 import java.lang.reflect.Constructor;
 20  
 import java.lang.reflect.InvocationHandler;
 21  
 import java.lang.reflect.Proxy;
 22  
 import java.util.HashMap;
 23  
 
 24  
 
 25  
 
 26  
 /**
 27  
  * @author andrew.clute
 28  
  *
 29  
  */
 30  
 public class ProxyFactoryJDKImpl extends AbstractProxyFactory {
 31  
 
 32  
     /**
 33  
      * JMM: Cache information about the interfaces need for dynamic proxy.
 34  
      */
 35  
     private HashMap foundInterfaces = new HashMap();
 36  
     
 37  
     
 38  
     public Class getDefaultIndirectionHandlerClass()
 39  
     {
 40  
         return IndirectionHandlerJDKImpl.class;
 41  
     }
 42  
     
 43  
     
 44  
     /**
 45  
      * Returns the class of the base class that the given IndirectionHandler must extend/implement
 46  
      * 
 47  
      */
 48  
     public Class getIndirectionHandlerBaseClass()
 49  
     {
 50  
         return IndirectionHandlerJDK.class;
 51  
     }
 52  
         
 53  
     
 54  
 
 55  
     public OJBProxy createProxy(Class baseClass, IndirectionHandler handler) throws Exception {
 56  
         Class proxyClass = getDynamicProxyClass(baseClass);
 57  
         Constructor constructor = proxyClass.getDeclaredConstructor(new Class[] { InvocationHandler.class });
 58  
         return (OJBProxy)constructor.newInstance(new Object[] { handler });
 59  
     }
 60  
 
 61  
     public IndirectionHandler getDynamicIndirectionHandler(Object obj) {
 62  
         return (IndirectionHandler)Proxy.getInvocationHandler(obj);
 63  
     }        
 64  
 
 65  
     public boolean isNormalOjbProxy(Object proxyOrObject) {
 66  
         return super.isNormalOjbProxy(proxyOrObject) && (proxyOrObject instanceof Proxy) && Proxy.isProxyClass(proxyOrObject.getClass());
 67  
     }
 68  
 
 69  
     /**
 70  
      * returns a dynamic Proxy that implements all interfaces of the
 71  
      * class described by this ClassDescriptor.
 72  
      *
 73  
      * @return Class the dynamically created proxy class
 74  
      */
 75  
     private Class getDynamicProxyClass(Class baseClass) {
 76  
         Class[] m_dynamicProxyClassInterfaces;
 77  
         if (foundInterfaces.containsKey(baseClass)) {
 78  
             m_dynamicProxyClassInterfaces = (Class[])foundInterfaces.get(baseClass);
 79  
         } else {
 80  
             m_dynamicProxyClassInterfaces = getInterfaces(baseClass);
 81  
             foundInterfaces.put(baseClass, m_dynamicProxyClassInterfaces);
 82  
         }
 83  
 
 84  
         // return dynymic Proxy Class implementing all interfaces
 85  
         Class proxyClazz = Proxy.getProxyClass(baseClass.getClassLoader(), m_dynamicProxyClassInterfaces);
 86  
         return proxyClazz;
 87  
     }
 88  
 
 89  
     /**
 90  
      * Get interfaces implemented by clazz
 91  
      *
 92  
      * @param clazz
 93  
      * @return
 94  
      */
 95  
     private Class[] getInterfaces(Class clazz) {
 96  
         Class superClazz = clazz;
 97  
         Class[] interfaces = clazz.getInterfaces();
 98  
 
 99  
         // clazz can be an interface itself and when getInterfaces()
 100  
         // is called on an interface it returns only the extending
 101  
         // interfaces, not the interface itself.
 102  
         if (clazz.isInterface()) {
 103  
             Class[] tempInterfaces = new Class[interfaces.length + 1];
 104  
             tempInterfaces[0] = clazz;
 105  
 
 106  
             System.arraycopy(interfaces, 0, tempInterfaces, 1, interfaces.length);
 107  
             interfaces = tempInterfaces;
 108  
         }
 109  
 
 110  
         // add all interfaces implemented by superclasses to the interfaces array
 111  
         while ((superClazz = superClazz.getSuperclass()) != null) {
 112  
             Class[] superInterfaces = superClazz.getInterfaces();
 113  
             Class[] combInterfaces = new Class[interfaces.length + superInterfaces.length];
 114  
             System.arraycopy(interfaces, 0, combInterfaces, 0, interfaces.length);
 115  
             System.arraycopy(superInterfaces, 0, combInterfaces, interfaces.length, superInterfaces.length);
 116  
             interfaces = combInterfaces;
 117  
         }
 118  
 
 119  
         /**
 120  
          * Must remove duplicate interfaces before calling Proxy.getProxyClass().
 121  
          * Duplicates can occur if a subclass re-declares that it implements
 122  
          * the same interface as one of its ancestor classes.
 123  
          **/
 124  
         HashMap unique = new HashMap();
 125  
         for (int i = 0; i < interfaces.length; i++) {
 126  
             unique.put(interfaces[i].getName(), interfaces[i]);
 127  
         }
 128  
         /* Add the OJBProxy interface as well */
 129  
         unique.put(OJBProxy.class.getName(), OJBProxy.class);
 130  
 
 131  
         interfaces = (Class[])unique.values().toArray(new Class[unique.size()]);
 132  
 
 133  
         return interfaces;
 134  
     }
 135  
     
 136  
     public boolean interfaceRequiredForProxyGeneration() {
 137  
         return true;
 138  
     }
 139  
 
 140  
 }