001package ca.uhn.fhir.util; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2016 University Health Network 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import java.lang.reflect.Field; 024import java.lang.reflect.Method; 025import java.lang.reflect.ParameterizedType; 026import java.lang.reflect.Type; 027import java.lang.reflect.TypeVariable; 028import java.lang.reflect.WildcardType; 029import java.util.LinkedHashSet; 030import java.util.List; 031 032public class ReflectionUtil { 033 034 /** 035 * For a field of type List<Enumeration<Foo>>, returns Foo 036 */ 037 public static Class<?> getGenericCollectionTypeOfFieldWithSecondOrderForList(Field next) { 038 if (!List.class.isAssignableFrom(next.getType())) { 039 return getGenericCollectionTypeOfField(next); 040 } 041 042 Class<?> type; 043 ParameterizedType collectionType = (ParameterizedType) next.getGenericType(); 044 Type firstArg = collectionType.getActualTypeArguments()[0]; 045 if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) { 046 ParameterizedType pt = ((ParameterizedType) firstArg); 047 Type pt2 = pt.getActualTypeArguments()[0]; 048 return (Class<?>) pt2; 049 } else { 050 type = (Class<?>) firstArg; 051 } 052 return type; 053 } 054 055 public static Class<?> getGenericCollectionTypeOfField(Field next) { 056 Class<?> type; 057 ParameterizedType collectionType = (ParameterizedType) next.getGenericType(); 058 Type firstArg = collectionType.getActualTypeArguments()[0]; 059 if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) { 060 ParameterizedType pt = ((ParameterizedType) firstArg); 061 type = (Class<?>) pt.getRawType(); 062 } else { 063 type = (Class<?>) firstArg; 064 } 065 return type; 066 } 067 068 public static Class<?> getGenericCollectionTypeOfMethodParameter(Method theMethod, int theParamIndex) { 069 Class<?> type; 070 Type genericParameterType = theMethod.getGenericParameterTypes()[theParamIndex]; 071 if (Class.class.equals(genericParameterType)) { 072 return null; 073 } 074 ParameterizedType collectionType = (ParameterizedType) genericParameterType; 075 Type firstArg = collectionType.getActualTypeArguments()[0]; 076 if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) { 077 ParameterizedType pt = ((ParameterizedType) firstArg); 078 type = (Class<?>) pt.getRawType(); 079 } else { 080 type = (Class<?>) firstArg; 081 } 082 return type; 083 } 084 085 @SuppressWarnings({ "rawtypes" }) 086 public static Class<?> getGenericCollectionTypeOfMethodReturnType(Method theMethod) { 087 Class<?> type; 088 Type genericReturnType = theMethod.getGenericReturnType(); 089 if (!(genericReturnType instanceof ParameterizedType)) { 090 return null; 091 } 092 ParameterizedType collectionType = (ParameterizedType) genericReturnType; 093 Type firstArg = collectionType.getActualTypeArguments()[0]; 094 if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) { 095 ParameterizedType pt = ((ParameterizedType) firstArg); 096 type = (Class<?>) pt.getRawType(); 097 } else if (firstArg instanceof TypeVariable<?>) { 098 Type decl = ((TypeVariable) firstArg).getBounds()[0]; 099 return (Class<?>) decl; 100 } else if (firstArg instanceof WildcardType) { 101 Type decl = ((WildcardType) firstArg).getUpperBounds()[0]; 102 return (Class<?>) decl; 103 } else { 104 type = (Class<?>) firstArg; 105 } 106 return type; 107 } 108 109 public static LinkedHashSet<Method> getDeclaredMethods(Class<?> theClazz) { 110 LinkedHashSet<Method> retVal = new LinkedHashSet<Method>(); 111 for (Method next : theClazz.getDeclaredMethods()) { 112 try { 113 Method method = theClazz.getMethod(next.getName(), next.getParameterTypes()); 114 retVal.add(method); 115 } catch (NoSuchMethodException e) { 116 retVal.add(next); 117 } catch (SecurityException e) { 118 retVal.add(next); 119 } 120 } 121 return retVal; 122 } 123 124}