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