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