/** * Copyright 2008-2016 Qualogy Solutions B.V. * * 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 com.qualogy.qafe.business.resource.java; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.qualogy.qafe.business.integration.adapter.PredefinedAdapterFactory; import com.qualogy.qafe.business.integration.builder.JavaTypeBuilder; public class ClassInfo { /** * methods holds [key][values] :: [methodName+parameterLength][list of methods fitting that description] */ private Map<String, List<Method>> methods; private ClassInfo(){ methods = new HashMap<String, List<Method>>(); } public static ClassInfo create(Class<?> clazz){ ClassInfo info = new ClassInfo(); info.gatherMethods(clazz); return info; } private void gatherMethods(Class<?> clazz){ Method[] classmethods = clazz.getMethods(); for (int i = 0; i < classmethods.length; i++) { String methodName = classmethods[i].getName(); methodName += classmethods[i].getParameterTypes().length; List<Method> methodsWithSameName = (List<Method>)methods.get(methodName); if (methodsWithSameName==null) { methodsWithSameName = new ArrayList<Method>(); } methodsWithSameName.add(classmethods[i]); methods.put(methodName, methodsWithSameName); } } public Method getMethod(String methodName, Class<?>[] parameterClasses) throws NoSuchMethodException{ if(methodName==null) throw new IllegalArgumentException("methodname cannot be null"); if(parameterClasses==null) throw new IllegalArgumentException("parameterObjectClassPairs cannot be null"); String key = methodName + parameterClasses.length; if(!methods.containsKey(key)) throw new NoSuchMethodException("Method " + methodName + " does not exist with " + parameterClasses.length + " args"); //narrow to find the correct method List<Method> themethods = new ArrayList<Method>((List<Method>)methods.get(methodName + parameterClasses.length)); for (Iterator<Method> iter = themethods.iterator(); iter.hasNext();) { Method method = (Method) iter.next(); Class<?>[] types = method.getParameterTypes(); for (int i = 0; i < types.length; i++) { if(types[i].isPrimitive() && parameterClasses[i]!=null){ Class<?> pClass = ((JavaTypeBuilder)PredefinedAdapterFactory.create(parameterClasses[i])).getPrimitiveClass(); if(pClass!=types[i]){//not the same primitive equivalent iter.remove(); break; } }else if(parameterClasses[i]!=null && !types[i].isAssignableFrom(parameterClasses[i])){ iter.remove();//not the same class when not null break; } } } if(themethods.size()>1){ throw new NoSuchMethodException("Cannot determine which of the overloaded methods with name " + methodName + " (and " + parameterClasses.length + " args) to use"); } if(themethods.size()==0){ String pClasses = ""; for (int i = 0; i < parameterClasses.length; i++) { if(i!=0) pClasses += ", "; pClasses += parameterClasses[i]; } throw new NoSuchMethodException("No method found for name " + methodName + " (and " + parameterClasses.length + " args ("+pClasses+")) to use"); } return (Method)themethods.get(0); } }