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