/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.config.reflect;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import com.caucho.config.inject.InjectManager;
import com.caucho.inject.Module;
/**
* Abstract introspected view of a Bean
*/
@Module
public class AnnotatedTypeUtil {
/**
* Finds any method matching the method name and parameter types.
*/
public static <X> AnnotatedMethod<? super X>
findMethod(AnnotatedType<X> type, AnnotatedMethod<?> method)
{
return findMethod(type.getMethods(), method);
}
/**
* Finds any method matching the method name and parameter types.
*/
public static <X> AnnotatedMethod<? super X>
findMethod(Collection<AnnotatedMethod<? super X>> methodList,
AnnotatedMethod<?> method)
{
Method javaMethod = method.getJavaMember();
String name = javaMethod.getName();
List<AnnotatedParameter<?>> paramList = (List) method.getParameters();
for (AnnotatedMethod<? super X> testMethod : methodList) {
Method testJavaMethod = testMethod.getJavaMember();
if (! name.equals(testJavaMethod.getName()))
continue;
List<AnnotatedParameter<?>> testParamList = (List) testMethod.getParameters();
if (isMatch(paramList, testParamList)) {
return testMethod;
}
}
return null;
}
private static boolean isMatch(List<AnnotatedParameter<?>> listA,
List<AnnotatedParameter<?>> listB)
{
if (listA.size() != listB.size())
return false;
int len = listA.size();
for (int i = 0; i < len; i++) {
if (! listA.get(i).getBaseType().equals(listB.get(i).getBaseType()))
return false;
}
return true;
}
/**
* Finds any method matching the method name and parameter types.
*/
public static <X> AnnotatedMethod<? super X>
findMethod(AnnotatedType<X> type, Method javaMethod)
{
return findMethod(type,
javaMethod.getName(),
javaMethod.getParameterTypes());
}
/**
* Finds any method matching the method name and parameter types.
*/
public static <X> AnnotatedMethod<? super X>
findMethod(AnnotatedType<X> type, String methodName, Class<?> []param)
{
for (AnnotatedMethod<? super X> annMethod : type.getMethods()) {
Method method = annMethod.getJavaMember();
if (! method.getName().equals(methodName))
continue;
if (isMatch(param, method.getParameterTypes()))
return annMethod;
}
return null;
}
/**
* Finds any method matching the method name and parameter types.
*/
public static <X> AnnotatedMethod<? super X>
findMethod(Set<AnnotatedMethod<? super X>> methods, Method method)
{
return findMethod(methods, method.getName(), method.getParameterTypes());
}
/**
* Finds any method matching the method name and parameter types.
*/
public static <X> AnnotatedMethod<? super X>
findMethod(Set<AnnotatedMethod<? super X>> methods, String methodName, Class<?> []param)
{
for (AnnotatedMethod<? super X> annMethod : methods) {
Method method = annMethod.getJavaMember();
if (! method.getName().equals(methodName))
continue;
if (isMatch(param, method.getParameterTypes()))
return annMethod;
}
return null;
}
/**
* Finds any method matching the method name and parameter types.
*/
public static Method findDeclaredMethod(Class<?> cl, Method testMethod)
{
if (cl == null)
return null;
for (Method method : cl.getDeclaredMethods()) {
if (isMatch(method, testMethod))
return method;
}
return null;
}
/**
* Finds any method matching the method name and parameter types.
*/
public static Method findMethod(Method []methods, Method testMethod)
{
for (Method method : methods) {
if (isMatch(method, testMethod))
return method;
}
return null;
}
/**
* Finds any method matching the method name and parameter types.
*/
public static Method findMethod(Collection<Method> methods, Method testMethod)
{
for (Method method : methods) {
if (isMatch(method, testMethod))
return method;
}
return null;
}
/**
* Tests if two annotated methods are equivalent.
*/
public static boolean isMatch(AnnotatedMethod<?> methodA,
AnnotatedMethod<?> methodB)
{
if (methodA == methodB)
return true;
else if (methodA == null || methodB == null)
return false;
Method javaMethodA = methodA.getJavaMember();
Method javaMethodB = methodB.getJavaMember();
if (! javaMethodA.getName().equals(javaMethodB.getName()))
return false;
List<AnnotatedParameter<?>> paramListA = (List) methodA.getParameters();
List<AnnotatedParameter<?>> paramListB = (List) methodB.getParameters();
if (isMatch(paramListA, paramListB)) {
return true;
}
return false;
}
/**
* Tests if an annotated method matches a name and parameter types.
*/
public static boolean isMatch(AnnotatedMethod<?> method,
String name, Class<?> []param)
{
Method javaMethod = method.getJavaMember();
if (! javaMethod.getName().equals(name))
return false;
Class<?> []mparam = javaMethod.getParameterTypes();
return isMatch(mparam, param);
}
/**
* Tests if an annotated method matches a name and parameter types.
*/
public static boolean isMatch(Method javaMethod,
String name, Class<?> []param)
{
if (! javaMethod.getName().equals(name))
return false;
Class<?> []mparam = javaMethod.getParameterTypes();
return isMatch(mparam, param);
}
/**
* Tests if an annotated method matches a name and parameter types.
*/
public static boolean isMatch(Method methodA, Method methodB)
{
if (! methodA.getName().equals(methodB.getName()))
return false;
return isMatch(methodA.getParameterTypes(),
methodB.getParameterTypes());
}
/**
* Tests if parameters match a method's parameter types.
*/
public static boolean isMatch(Class<?> []paramA, Class<?> []paramB)
{
if (paramA.length != paramB.length)
return false;
for (int i = paramA.length - 1; i >= 0; i--) {
if (! paramA[i].equals(paramB[i]))
return false;
}
return true;
}
/**
* Tests if a method throws a checked exception.
*/
public static boolean hasException(AnnotatedMethod<?> method, Class<?> exn)
{
Class<?> []methodExceptions = method.getJavaMember().getExceptionTypes();
for (int j = 0; j < methodExceptions.length; j++) {
if (methodExceptions[j].isAssignableFrom(exn))
return true;
}
return false;
}
public static BaseType getBaseType(Annotated annotated)
{
if (annotated instanceof BaseTypeAnnotated)
return ((BaseTypeAnnotated) annotated).getBaseTypeImpl();
else
return InjectManager.create().createTargetBaseType(annotated.getBaseType());
}
}