001    package org.apache.fulcrum.yaafi.framework.reflection;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.lang.reflect.Constructor;
023    import java.lang.reflect.InvocationTargetException;
024    import java.lang.reflect.Method;
025    import java.util.ArrayList;
026    import java.util.Iterator;
027    import java.util.List;
028    
029    /**
030     * Helper clazz to do a little bit of reflection magic.
031     *
032     * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
033     */
034    
035    public class Clazz
036    {
037        /**
038         * Determine if the class can be loaded.
039         *
040         * @param classLoader the classloader to be used
041         * @param clazzName the name of the class to be loaded
042         * @return true if the class was found
043         */
044        public static boolean hasClazz( ClassLoader classLoader, String clazzName )
045        {
046            try
047            {
048                classLoader.loadClass( clazzName );
049                return true;
050            }
051            catch (ClassNotFoundException e)
052            {
053                return false;
054            }
055        }
056    
057        /**
058         * Loads a class with the given name.
059         * @param classLoader the class loader to be used
060         * @param clazzName the name of the clazz to be loaded
061         * @return the loaded class
062         * @throws ClassNotFoundException the class was nout found
063         */
064        public static Class getClazz( ClassLoader classLoader, String clazzName )
065            throws ClassNotFoundException
066        {
067            return classLoader.loadClass( clazzName );
068        }
069    
070        /**
071         * Creates a new instance of the class
072         * @param clazz the class to be instantiated
073         * @param signature the signature of the constructor
074         * @param args the arguments to be passed
075         * @return the newly created instance
076         * @throws NoSuchMethodException the method was not found
077         * @throws InvocationTargetException an exception was thrown in the constructor
078         * @throws InstantiationException the target class could not be instantiated
079         * @throws IllegalAccessException an field couldn't be accessed
080         */
081        public static Object newInstance( Class clazz, Class[] signature, Object[] args )
082            throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException
083        {
084            Object result = null;
085            Constructor constructor = clazz.getConstructor( signature );
086            result = constructor.newInstance( args );
087            return result;
088        }
089    
090        /**
091         * Invokes a given method on the instance.
092         * @param instance the instance
093         * @param methodName the name of the method to be invoked
094         * @param signature the signature of the method
095         * @param args the arguments for the method invocation
096         * @return the result of the method invocation
097         * @throws NoSuchMethodException the method was not found
098         * @throws InvocationTargetException an exception was thrown in the constructor
099         * @throws IllegalAccessException an field couldn't be accessed
100         */
101        public static Object invoke( Object instance, String methodName, Class[] signature, Object[] args )
102            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
103        {
104            Object result = null;
105            Method method = instance.getClass().getMethod( methodName, signature );
106            result = method.invoke( instance, args );
107            return result;
108        }
109    
110        /**
111         * Invokes a static method on a class.
112         * @param clazz the class instance to work on
113         * @param methodName the name of the method to be invoked
114         * @param signature the signature of the method
115         * @param args the arguments for the method invocation
116         * @return the result of the method invocation
117         * @throws NoSuchMethodException the method was not found
118         * @throws InvocationTargetException an exception was thrown in the constructor
119         * @throws IllegalAccessException an field couldn't be accessed
120         */
121    
122        public static Object invoke( Class clazz, String methodName, Class[] signature, Object[] args )
123            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
124        {
125            Object result = null;
126            Method method = clazz.getMethod( methodName, signature );
127            result = method.invoke( null, args );
128            return result;
129        }
130    
131        /**
132         * <p>Gets a <code>List</code> of all interfaces implemented by the given
133         * class and its superclasses.</p>
134         *
135         * <p>The order is determined by looking through each interface in turn as
136         * declared in the source file and following its hierarchy up. Then each
137         * superclass is considered in the same way. Later duplicates are ignored,
138         * so the order is maintained.</p>
139         *
140         * @param cls  the class to look up, may be <code>null</code>
141         * @return the <code>List</code> of interfaces in order,
142         *  <code>null</code> if null input
143         */
144        public static List getAllInterfaces(Class cls)
145        {
146            if (cls == null)
147            {
148                return null;
149            }
150            List list = new ArrayList();
151            while (cls != null)
152            {
153                Class [] interfaces = cls.getInterfaces();
154                for (int i = 0; i < interfaces.length; i++)
155                {
156                    if (list.contains( interfaces[i] ) == false)
157                    {
158                        list.add( interfaces[i] );
159                    }
160                    List superInterfaces = getAllInterfaces( interfaces[i] );
161                    for (Iterator it = superInterfaces.iterator(); it.hasNext();)
162                    {
163                        Class intface = (Class) it.next();
164                        if (list.contains( intface ) == false)
165                        {
166                            list.add( intface );
167                        }
168                    }
169                }
170                cls = cls.getSuperclass();
171            }
172            return list;
173        }
174    }