001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.proxy; 019 020 import org.apache.commons.proxy.invoker.NullInvoker; 021 022 import java.util.LinkedList; 023 import java.util.List; 024 import java.util.Map; 025 import java.util.HashMap; 026 027 /** 028 * Provides some helpful proxy utility methods. 029 * 030 * @author James Carman 031 * @since 1.0 032 */ 033 public class ProxyUtils 034 { 035 //---------------------------------------------------------------------------------------------------------------------- 036 // Fields 037 //---------------------------------------------------------------------------------------------------------------------- 038 039 public static final Object[] EMPTY_ARGUMENTS = new Object[0]; 040 public static final Class[] EMPTY_ARGUMENT_TYPES = new Class[0]; 041 private static final Map wrapperClassMap = new HashMap(); 042 043 //---------------------------------------------------------------------------------------------------------------------- 044 // Static Methods 045 //---------------------------------------------------------------------------------------------------------------------- 046 047 static 048 { 049 wrapperClassMap.put( Integer.TYPE, Integer.class ); 050 wrapperClassMap.put( Character.TYPE, Character.class ); 051 wrapperClassMap.put( Boolean.TYPE, Boolean.class ); 052 wrapperClassMap.put( Short.TYPE, Short.class ); 053 wrapperClassMap.put( Long.TYPE, Long.class ); 054 wrapperClassMap.put( Float.TYPE, Float.class ); 055 wrapperClassMap.put( Double.TYPE, Double.class ); 056 wrapperClassMap.put( Byte.TYPE, Byte.class ); 057 } 058 /** 059 * Creates a "null object" which implements the <code>proxyClasses</code>. 060 * 061 * @param proxyFactory the proxy factory to be used to create the proxy object 062 * @param proxyClasses the proxy interfaces 063 * @return a "null object" which implements the <code>proxyClasses</code>. 064 */ 065 public static Object createNullObject( ProxyFactory proxyFactory, Class[] proxyClasses ) 066 { 067 return proxyFactory.createInvokerProxy( new NullInvoker(), proxyClasses ); 068 } 069 070 /** 071 * Creates a "null object" which implements the <code>proxyClasses</code>. 072 * 073 * @param proxyFactory the proxy factory to be used to create the proxy object 074 * @param classLoader the class loader to be used by the proxy factory to create the proxy object 075 * @param proxyClasses the proxy interfaces 076 * @return a "null object" which implements the <code>proxyClasses</code>. 077 */ 078 public static Object createNullObject( ProxyFactory proxyFactory, ClassLoader classLoader, Class[] proxyClasses ) 079 { 080 return proxyFactory.createInvokerProxy( classLoader, new NullInvoker(), proxyClasses ); 081 } 082 083 /** 084 * <p>Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its 085 * superclasses.</p> 086 * <p/> 087 * <p>The order is determined by looking through each interface in turn as declared in the source file and following 088 * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order 089 * is maintained.</p> 090 * <p/> 091 * <b>Note</b>: Implementation of this method was "borrowed" from 092 * <a href="http://commons.apache.org/lang/">Apache Commons Lang</a> to avoid a dependency.</p> 093 * 094 * @param cls the class to look up, may be <code>null</code> 095 * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its 096 * superclasses or <code>null</code> if input class is null. 097 */ 098 public static Class[] getAllInterfaces( Class cls ) 099 { 100 final List interfaces = getAllInterfacesImpl( cls, new LinkedList() ); 101 return interfaces == null ? null : ( Class[] ) interfaces.toArray( new Class[interfaces.size()] ); 102 } 103 104 private static List getAllInterfacesImpl( Class cls, List list ) 105 { 106 if( cls == null ) 107 { 108 return null; 109 } 110 while( cls != null ) 111 { 112 Class[] interfaces = cls.getInterfaces(); 113 for( int i = 0; i < interfaces.length; i++ ) 114 { 115 if( !list.contains( interfaces[i] ) ) 116 { 117 list.add( interfaces[i] ); 118 } 119 getAllInterfacesImpl( interfaces[i], list ); 120 } 121 cls = cls.getSuperclass(); 122 } 123 return list; 124 } 125 126 /** 127 * Returns the class name as you would expect to see it in Java code. 128 * <p/> 129 * <b>Examples:</b> <ul> <li>getJavaClassName( Object[].class ) == "Object[]"</li> <li>getJavaClassName( 130 * Object[][].class ) == "Object[][]"</li> <li>getJavaClassName( Integer.TYPE ) == "int"</li> </p> 131 * 132 * @param clazz the class 133 * @return the class' name as you would expect to see it in Java code 134 */ 135 public static String getJavaClassName( Class clazz ) 136 { 137 if( clazz.isArray() ) 138 { 139 return getJavaClassName( clazz.getComponentType() ) + "[]"; 140 } 141 return clazz.getName(); 142 } 143 144 /** 145 * Returns the wrapper class for the given primitive type. 146 * @param primitiveType the primitive type 147 * @return the wrapper class 148 */ 149 public static Class getWrapperClass( Class primitiveType ) 150 { 151 return ( Class )wrapperClassMap.get( primitiveType ); 152 } 153 } 154