/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "SOAP" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.soap.util;
import java.util.*;
import java.io.*;
import java.beans.*;
import java.lang.reflect.*;
/**
* This file is a collection of reflection utilities for dealing with
* methods and constructors.
*
* @author Sanjiva Weerawarana
* @author Joseph Kesselman
*/
public class MethodUtils {
//////////////////////////////////////////////////////////////////////////
/**
* Search for entry point, per Java Language Spec 1.0
* as amended, verified by comparison against compiler behavior.
*
* @param targetClass Class object for the class to be queried.
* @param methodName Name of method to invoke, or null for constructor.
* Only Public methods will be accepted.
* @param argTypes Classes of intended arguments. Note that primitives
* must be specified via their TYPE equivalents,
* rather than as their wrapper classes -- Integer.TYPE
* rather than Integer. "null" may be passed in as an
* indication that you intend to invoke the method with
* a literal null argument and therefore can accept
* any object type in this position.
* @param isStaticReference If true, and if the target is a Class object,
* only static methods will be accepted as valid matches.
*
* @return a Method or Constructor of the appropriate signature
*
* @exception SecurityException if security violation
* @exception NoSuchMethodException if no such method
*/
static private Object getEntryPoint(Class targetClass,
String methodName,
Class[] argTypes,
boolean isStaticReference)
throws SecurityException, NoSuchMethodException
{
// 15.11.1: OBTAIN STARTING CLASS FOR SEARCH
Object m=null;
// 15.11.2 DETERMINE ARGUMENT SIGNATURE
// (Passed in as argTypes array.)
// Shortcut: If an exact match exists, return it.
try {
if(methodName!=null)
{
m=targetClass.getMethod (methodName, argTypes);
if(isStaticReference &&
!Modifier.isStatic(entryGetModifiers(m)) )
{
throw
new NoSuchMethodException (callToString (targetClass,
methodName,
argTypes,
isStaticReference)+
" resolved to instance " + m);
}
return m;
}
else
return targetClass.getConstructor (argTypes);
} catch (NoSuchMethodException e) {
// no-args has no alternatives!
if(argTypes==null || argTypes.length==0)
{
throw
new NoSuchMethodException (callToString (targetClass,
methodName,
argTypes,
isStaticReference)+
" not found.");
}
// Else fall through.
}
// Well, _that_ didn't work. Time to search for the Most Specific
// matching function. NOTE that conflicts are possible!
// 15.11.2.1 ACCESSIBLE: We apparently need to gather from two
// sources to be sure we have both instance and static methods.
Object[] methods;
if(methodName!=null)
{
methods=targetClass.getMethods();
}
else
{
methods=targetClass.getConstructors();
}
if(0==methods.length)
{
throw new NoSuchMethodException("No methods!");
}
MoreSpecific best=new MoreSpecific();
for(int i=0;i<methods.length;++i)
{
Object mi=methods[i];
if (
// 15.11.2.1 ACCESSIBLE: Method is public.
Modifier.isPublic(entryGetModifiers(mi))
&&
// 15.11.2.1 APPLICABLE: Right method name (or c'tor)
(methodName==null || entryGetName(mi).equals(methodName) )
&&
// 15.11.2.1 APPLICABLE: Parameters match arguments
areMethodConvertable(entryGetParameterTypes(mi),argTypes)
)
// 15.11.2.2 MORE SPECIFIC displace less specific.
best.addItem(mi);
}
// May throw NoSuchMethodException; we pass in info needed to
// create a useful exception
m=best.getMostSpecific(targetClass,methodName,argTypes,isStaticReference);
// 15.11.3 APPROPRIATE: Class invocation can call only static
// methods. Note that the defined order of evaluation permits a
// call to be resolved to an inappropriate method and then
// rejected, rather than finding the best of the appropriate
// methods.
//
// Constructors are never static, so we don't test them.
if(m==null)
{
throw new NoSuchMethodException (