001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.util.reflect;
019
020import java.lang.reflect.InvocationTargetException;
021import java.lang.reflect.Method;
022import java.sql.SQLException;
023import java.util.HashSet;
024import java.util.LinkedList;
025import java.util.List;
026import java.util.Set;
027import java.util.regex.Pattern;
028
029import net.sf.hajdbc.ExceptionFactory;
030
031/**
032 * @author Paul Ferraro
033 */
034public final class Methods
035{
036        /**
037         * Helper method for <code>Method.invoke(Object, Object...)</code> that performs the necessary exception handling.
038         * @param method a method to invoke
039         * @param object the object on which to invoke the given method
040         * @param parameters the method parameters
041         * @return the return value of the method invocation
042         * @throws SQLException the target exception of the method invocation
043         * @throws IllegalArgumentException if the the underlying method is inaccessible
044         */
045        public static <R, E extends Exception> R invoke(Method method, ExceptionFactory<E> factory, Object object, Object... parameters) throws E
046        {
047                try
048                {
049                        return (R) method.invoke(object, parameters);
050                }
051                catch (InvocationTargetException e)
052                {
053                        throw factory.createException(e.getTargetException());
054                }
055                catch (IllegalAccessException e)
056                {
057                        throw factory.createException(e);
058                }
059        }
060        
061        /**
062         * Returns a set of methods for the specified class whose names match the specified regular expression patterns.
063         * @param sourceClass the class from which to find methods
064         * @param patterns regular expression patterns
065         * @return a set of methods
066         */
067        public static Set<Method> findMethods(Class<?> sourceClass, String... patterns)
068        {
069                List<Method> list = new LinkedList<Method>();
070                
071                Method[] methods = sourceClass.getMethods();
072                
073                for (String regex: patterns)
074                {
075                        Pattern pattern = Pattern.compile(regex);
076                        
077                        for (Method method: methods)
078                        {
079                                if (pattern.matcher(method.getName()).matches())
080                                {
081                                        list.add(method);
082                                }
083                        }
084                }
085                
086                return new HashSet<Method>(list);
087        }
088        
089        /**
090         * Helper method for {@link Class#getMethod(String, Class...)} where method is known to exist.
091         * @param sourceClass the class from which to find methods
092         * @param name the method name
093         * @param types the parameter types
094         * @return the method with the specified name and parameter types
095         * @throws IllegalArgumentException if no such method exists
096         */
097        public static Method getMethod(Class<?> sourceClass, String name, Class<?>... types)
098        {
099                try
100                {
101                        return sourceClass.getMethod(name, types);
102                }
103                catch (NoSuchMethodException e)
104                {
105                        throw new IllegalArgumentException(e);
106                }
107        }
108        
109        /**
110         * Helper method for {@link Class#getMethod(String, Class...)} that returns null if the method does not exist.
111         * @param sourceClass the class from which to find methods
112         * @param name the method name
113         * @param types the parameter types
114         * @return the method with the specified name and parameter types, or null if the method does not exist
115         */
116        public static Method findMethod(Class<?> sourceClass, String name, Class<?>... types)
117        {
118                try
119                {
120                        return sourceClass.getMethod(name, types);
121                }
122                catch (NoSuchMethodException e)
123                {
124                        return null;
125                }
126        }
127        
128        /**
129         * Helper method for {@link Class#getMethod(String, Class...)} that returns null if the class or method does not exist.
130         * @param className the name of the class containing the method
131         * @param name the method name
132         * @param types the parameter types
133         * @return the method with the specified name and parameter types, or null if the class or method does not exist
134         */
135        public static Method findMethod(String className, String name, Class<?>... types)
136        {
137                try
138                {
139                        return findMethod(Methods.class.getClassLoader().loadClass(className), name, types);
140                }
141                catch (ClassNotFoundException e)
142                {
143                        return null;
144                }
145        }
146        
147        private Methods()
148        {
149                // Hide constructor
150        }
151}