--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import com.sun.beans.WeakCache;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public method with specified name and parameter types
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class MethodFinder extends AbstractFinder<Method> {
+ private static final WeakCache<Signature, Method> CACHE = new WeakCache<Signature, Method>();
+
+ /**
+ * Finds public method (static or non-static)
+ * that is accessible from public class.
+ *
+ * @param type the class that can have method
+ * @param name the name of method to find
+ * @param args parameter types that is used to find method
+ * @return object that represents found method
+ * @throws NoSuchMethodException if method could not be found
+ * or some methods are found
+ */
+ public static Method findMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
+ if (name == null) {
+ throw new IllegalArgumentException("Method name is not set");
+ }
+ PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
+ Signature signature = new Signature(type, name, args);
+
+ Method method = CACHE.get(signature);
+ if (method != null) {
+ return method;
+ }
+ method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
+ CACHE.put(signature, method);
+ return method;
+ }
+
+ /**
+ * Finds public non-static method
+ * that is accessible from public class.
+ *
+ * @param type the class that can have method
+ * @param name the name of method to find
+ * @param args parameter types that is used to find method
+ * @return object that represents found method
+ * @throws NoSuchMethodException if method could not be found
+ * or some methods are found
+ */
+ public static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) throws NoSuchMethodException {
+ Method method = findMethod(type, name, args);
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new NoSuchMethodException("Method '" + name + "' is static");
+ }
+ return method;
+ }
+
+ /**
+ * Finds public static method
+ * that is accessible from public class.
+ *
+ * @param type the class that can have method
+ * @param name the name of method to find
+ * @param args parameter types that is used to find method
+ * @return object that represents found method
+ * @throws NoSuchMethodException if method could not be found
+ * or some methods are found
+ */
+ public static Method findStaticMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
+ Method method = findMethod(type, name, args);
+ if (!Modifier.isStatic(method.getModifiers())) {
+ throw new NoSuchMethodException("Method '" + name + "' is not static");
+ }
+ return method;
+ }
+
+ /**
+ * Finds method that is accessible from public class or interface through class hierarchy.
+ *
+ * @param method object that represents found method
+ * @return object that represents accessible method
+ * @throws NoSuchMethodException if method is not accessible or is not found
+ * in specified superclass or interface
+ */
+ private static Method findAccessibleMethod(Method method) throws NoSuchMethodException {
+ Class<?> type = method.getDeclaringClass();
+ if (Modifier.isPublic(type.getModifiers())) {
+ return method;
+ }
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible");
+ }
+ for (Class<?> face : type.getInterfaces()) {
+ try {
+ return findAccessibleMethod(method, face);
+ }
+ catch (NoSuchMethodException exception) {
+ // try to find in superclass or another interface
+ }
+ }
+ return findAccessibleMethod(method, type.getSuperclass());
+ }
+
+ /**
+ * Finds method that accessible from specified class.
+ *
+ * @param method object that represents found method
+ * @param type class that is used to find accessible method
+ * @return object that represents accessible method
+ * @throws NoSuchMethodException if method is not accessible or is not found
+ * in specified superclass or interface
+ */
+ private static Method findAccessibleMethod(Method method, Class<?> type) throws NoSuchMethodException {
+ String name = method.getName();
+ Class<?>[] params = method.getParameterTypes();
+ return findAccessibleMethod(type.getMethod(name, params));
+ }
+
+
+ private final String name;
+
+ /**
+ * Creates method finder with specified array of parameter types.
+ *
+ * @param name the name of method to find
+ * @param args the array of parameter types
+ */
+ private MethodFinder(String name, Class<?>[] args) {
+ super(args);
+ this.name = name;
+ }
+
+ /**
+ * Returns an array of {@code Class} objects
+ * that represent the formal parameter types of the method
+ * Returns an empty array if the method takes no parameters.
+ *
+ * @param method the object that represents method
+ * @return the parameter types of the method
+ */
+ @Override
+ protected Class<?>[] getParameters(Method method) {
+ return method.getParameterTypes();
+ }
+
+ /**
+ * Returns {@code true} if and only if the method
+ * was declared to take a variable number of arguments.
+ *
+ * @param method the object that represents method
+ * @return {@code true} if the method was declared
+ * to take a variable number of arguments;
+ * {@code false} otherwise
+ */
+ @Override
+ protected boolean isVarArgs(Method method) {
+ return method.isVarArgs();
+ }
+
+ /**
+ * Checks validness of the method.
+ * The valid method should be public and
+ * should have the specified name.
+ *
+ * @param method the object that represents method
+ * @return {@code true} if the method is valid,
+ * {@code false} otherwise
+ */
+ @Override
+ protected boolean isValid(Method method) {
+ return Modifier.isPublic(method.getModifiers()) && method.getName().equals(this.name);
+ }
+}