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.HashMap;
023 import java.util.LinkedList;
024 import java.util.List;
025 import java.util.Map;
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 /**
060 * Creates a "null object" which implements the <code>proxyClasses</code>.
061 *
062 * @param proxyFactory the proxy factory to be used to create the proxy object
063 * @param proxyClasses the proxy interfaces
064 * @return a "null object" which implements the <code>proxyClasses</code>.
065 */
066 public static Object createNullObject( ProxyFactory proxyFactory, Class[] proxyClasses )
067 {
068 return proxyFactory.createInvokerProxy(new NullInvoker(), proxyClasses);
069 }
070
071 /**
072 * Creates a "null object" which implements the <code>proxyClasses</code>.
073 *
074 * @param proxyFactory the proxy factory to be used to create the proxy object
075 * @param classLoader the class loader to be used by the proxy factory to create the proxy object
076 * @param proxyClasses the proxy interfaces
077 * @return a "null object" which implements the <code>proxyClasses</code>.
078 */
079 public static Object createNullObject( ProxyFactory proxyFactory, ClassLoader classLoader, Class[] proxyClasses )
080 {
081 return proxyFactory.createInvokerProxy(classLoader, new NullInvoker(), proxyClasses);
082 }
083
084 /**
085 * <p>Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its
086 * superclasses.</p>
087 * <p/>
088 * <p>The order is determined by looking through each interface in turn as declared in the source file and following
089 * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order
090 * is maintained.</p>
091 * <p/>
092 * <b>Note</b>: Implementation of this method was "borrowed" from
093 * <a href="http://commons.apache.org/lang/">Apache Commons Lang</a> to avoid a dependency.</p>
094 *
095 * @param cls the class to look up, may be <code>null</code>
096 * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its
097 * superclasses or <code>null</code> if input class is null.
098 */
099 public static Class[] getAllInterfaces( Class cls )
100 {
101 final List interfaces = getAllInterfacesImpl(cls, new LinkedList());
102 return interfaces == null ? null : ( Class[] ) interfaces.toArray(new Class[interfaces.size()]);
103 }
104
105 private static List getAllInterfacesImpl( Class cls, List list )
106 {
107 if( cls == null )
108 {
109 return null;
110 }
111 while( cls != null )
112 {
113 Class[] interfaces = cls.getInterfaces();
114 for( int i = 0; i < interfaces.length; i++ )
115 {
116 if( !list.contains(interfaces[i]) )
117 {
118 list.add(interfaces[i]);
119 }
120 getAllInterfacesImpl(interfaces[i], list);
121 }
122 cls = cls.getSuperclass();
123 }
124 return list;
125 }
126
127 /**
128 * Returns the class name as you would expect to see it in Java code.
129 * <p/>
130 * <b>Examples:</b> <ul> <li>getJavaClassName( Object[].class ) == "Object[]"</li> <li>getJavaClassName(
131 * Object[][].class ) == "Object[][]"</li> <li>getJavaClassName( Integer.TYPE ) == "int"</li> </p>
132 *
133 * @param clazz the class
134 * @return the class' name as you would expect to see it in Java code
135 */
136 public static String getJavaClassName( Class clazz )
137 {
138 if( clazz.isArray() )
139 {
140 return getJavaClassName(clazz.getComponentType()) + "[]";
141 }
142 return clazz.getName();
143 }
144
145 /**
146 * Returns the wrapper class for the given primitive type.
147 *
148 * @param primitiveType the primitive type
149 * @return the wrapper class
150 */
151 public static Class getWrapperClass( Class primitiveType )
152 {
153 return ( Class ) wrapperClassMap.get(primitiveType);
154 }
155 }
156