|
What this is
Other links
The source code/* * Copyright 1999-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.jxpath.util; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import org.apache.commons.jxpath.ExpressionContext; import org.apache.commons.jxpath.JXPathException; /** * Method lookup utilities, which find static and non-static methods as well * as constructors based on a name and list of parameters. * * @author Dmitri Plotnikov * @version $Revision: 1.7 $ $Date: 2004/02/29 14:17:43 $ */ public class MethodLookupUtils { private static final int NO_MATCH = 0; private static final int APPROXIMATE_MATCH = 1; private static final int EXACT_MATCH = 2; private static final Object[] EMPTY_ARRAY = new Object[0]; public static Constructor lookupConstructor( Class targetClass, Object[] parameters) { boolean tryExact = true; int count = parameters == null ? 0 : parameters.length; Class types[] = new Class[count]; for (int i = 0; i < count; i++) { Object param = parameters[i]; if (param != null) { types[i] = param.getClass(); } else { types[i] = null; tryExact = false; } } Constructor constructor = null; if (tryExact) { // First - without type conversion try { constructor = targetClass.getConstructor(types); if (constructor != null) { return constructor; } } catch (NoSuchMethodException ex) { // Ignore } } int currentMatch = 0; boolean ambiguous = false; // Then - with type conversion Constructor[] constructors = targetClass.getConstructors(); for (int i = 0; i < constructors.length; i++) { int match = matchParameterTypes( constructors[i].getParameterTypes(), parameters); if (match != NO_MATCH) { if (match > currentMatch) { constructor = constructors[i]; currentMatch = match; ambiguous = false; } else if (match == currentMatch) { ambiguous = true; } } } if (ambiguous) { throw new JXPathException( "Ambigous constructor " + Arrays.asList(parameters)); } return constructor; } public static Method lookupStaticMethod( Class targetClass, String name, Object[] parameters) { boolean tryExact = true; int count = parameters == null ? 0 : parameters.length; Class types[] = new Class[count]; for (int i = 0; i < count; i++) { Object param = parameters[i]; if (param != null) { types[i] = param.getClass(); } else { types[i] = null; tryExact = false; } } Method method = null; if (tryExact) { // First - without type conversion try { method = targetClass.getMethod(name, types); if (method != null && Modifier.isStatic(method.getModifiers())) { return method; } } catch (NoSuchMethodException ex) { // Ignore } } int currentMatch = 0; boolean ambiguous = false; // Then - with type conversion Method[] methods = targetClass.getMethods(); for (int i = 0; i < methods.length; i++) { if (Modifier.isStatic(methods[i].getModifiers()) && methods[i].getName().equals(name)) { int match = matchParameterTypes( methods[i].getParameterTypes(), parameters); if (match != NO_MATCH) { if (match > currentMatch) { method = methods[i]; currentMatch = match; ambiguous = false; } else if (match == currentMatch) { ambiguous = true; } } } } if (ambiguous) { throw new JXPathException("Ambigous method call: " + name); } return method; } public static Method lookupMethod( Class targetClass, String name, Object[] parameters) { if (parameters == null || parameters.length < 1 || parameters[0] == null) { return null; } if (matchType(targetClass, parameters[0]) == NO_MATCH) { return null; } targetClass = TypeUtils.convert(parameters[0], targetClass).getClass(); boolean tryExact = true; int count = parameters.length - 1; Class types[] = new Class[count]; Object arguments[] = new Object[count]; for (int i = 0; i < count; i++) { Object param = parameters[i + 1]; arguments[i] = param; if (param != null) { types[i] = param.getClass(); } else { types[i] = null; tryExact = false; } } Method method = null; if (tryExact) { // First - without type conversion try { method = targetClass.getMethod(name, types); if (method != null && !Modifier.isStatic(method.getModifiers())) { return method; } } catch (NoSuchMethodException ex) { // Ignore } } int currentMatch = 0; boolean ambiguous = false; // Then - with type conversion Method[] methods = targetClass.getMethods(); for (int i = 0; i < methods.length; i++) { if (!Modifier.isStatic(methods[i].getModifiers()) && methods[i].getName().equals(name)) { int match = matchParameterTypes( methods[i].getParameterTypes(), arguments); if (match != NO_MATCH) { if (match > currentMatch) { method = methods[i]; currentMatch = match; ambiguous = false; } else if (match == currentMatch) { ambiguous = true; } } } } if (ambiguous) { throw new JXPathException("Ambigous method call: " + name); } return method; } private static int matchParameterTypes( Class types[], Object parameters[]) { int pi = 0; if (types.length >= 1 && ExpressionContext.class.isAssignableFrom(types[0])) { pi++; } int length = parameters == null ? 0 : parameters.length; if (types.length != length + pi) { return NO_MATCH; } int totalMatch = EXACT_MATCH; for (int i = 0; i < length; i++) { int match = matchType(types[i + pi], parameters[i]); if (match == NO_MATCH) { return NO_MATCH; } if (match < totalMatch) { totalMatch = match; } } return totalMatch; } private static int matchType(Class expected, Object object) { if (object == null) { return APPROXIMATE_MATCH; } Class actual = object.getClass(); if (expected.equals(actual)) { return EXACT_MATCH; } if (expected.isAssignableFrom(actual)) { return EXACT_MATCH; } if (TypeUtils.canConvert(object, expected)) { return APPROXIMATE_MATCH; } return NO_MATCH; } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.