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