ca.uhn.fhir.util.ReflectionUtil.java Source code

Java tutorial

Introduction

Here is the source code for ca.uhn.fhir.util.ReflectionUtil.java

Source

package ca.uhn.fhir.util;

/*
 * #%L
 * HAPI FHIR - Core Library
 * %%
 * Copyright (C) 2014 - 2017 University Health Network
 * %%
 * 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.
 * #L%
 */

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.LinkedHashSet;
import java.util.List;

import org.apache.commons.lang3.Validate;

import ca.uhn.fhir.context.ConfigurationException;
import javassist.Modifier;

public class ReflectionUtil {

    private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReflectionUtil.class);

    public static LinkedHashSet<Method> getDeclaredMethods(Class<?> theClazz) {
        LinkedHashSet<Method> retVal = new LinkedHashSet<Method>();
        for (Method next : theClazz.getDeclaredMethods()) {
            try {
                Method method = theClazz.getMethod(next.getName(), next.getParameterTypes());
                retVal.add(method);
            } catch (NoSuchMethodException e) {
                retVal.add(next);
            } catch (SecurityException e) {
                retVal.add(next);
            }
        }
        return retVal;
    }

    public static Class<?> getGenericCollectionTypeOfField(Field next) {
        Class<?> type;
        ParameterizedType collectionType = (ParameterizedType) next.getGenericType();
        Type firstArg = collectionType.getActualTypeArguments()[0];
        if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) {
            ParameterizedType pt = ((ParameterizedType) firstArg);
            type = (Class<?>) pt.getRawType();
        } else {
            type = (Class<?>) firstArg;
        }
        return type;
    }

    /**
     * For a field of type List<Enumeration<Foo>>, returns Foo
     */
    public static Class<?> getGenericCollectionTypeOfFieldWithSecondOrderForList(Field next) {
        if (!List.class.isAssignableFrom(next.getType())) {
            return getGenericCollectionTypeOfField(next);
        }

        Class<?> type;
        ParameterizedType collectionType = (ParameterizedType) next.getGenericType();
        Type firstArg = collectionType.getActualTypeArguments()[0];
        if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) {
            ParameterizedType pt = ((ParameterizedType) firstArg);
            Type pt2 = pt.getActualTypeArguments()[0];
            return (Class<?>) pt2;
        }
        type = (Class<?>) firstArg;
        return type;
    }

    public static Class<?> getGenericCollectionTypeOfMethodParameter(Method theMethod, int theParamIndex) {
        Class<?> type;
        Type genericParameterType = theMethod.getGenericParameterTypes()[theParamIndex];
        if (Class.class.equals(genericParameterType)) {
            return null;
        }
        ParameterizedType collectionType = (ParameterizedType) genericParameterType;
        Type firstArg = collectionType.getActualTypeArguments()[0];
        if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) {
            ParameterizedType pt = ((ParameterizedType) firstArg);
            type = (Class<?>) pt.getRawType();
        } else {
            type = (Class<?>) firstArg;
        }
        return type;
    }

    @SuppressWarnings({ "rawtypes" })
    public static Class<?> getGenericCollectionTypeOfMethodReturnType(Method theMethod) {
        Class<?> type;
        Type genericReturnType = theMethod.getGenericReturnType();
        if (!(genericReturnType instanceof ParameterizedType)) {
            return null;
        }
        ParameterizedType collectionType = (ParameterizedType) genericReturnType;
        Type firstArg = collectionType.getActualTypeArguments()[0];
        if (ParameterizedType.class.isAssignableFrom(firstArg.getClass())) {
            ParameterizedType pt = ((ParameterizedType) firstArg);
            type = (Class<?>) pt.getRawType();
        } else if (firstArg instanceof TypeVariable<?>) {
            Type decl = ((TypeVariable) firstArg).getBounds()[0];
            return (Class<?>) decl;
        } else if (firstArg instanceof WildcardType) {
            Type decl = ((WildcardType) firstArg).getUpperBounds()[0];
            return (Class<?>) decl;
        } else {
            type = (Class<?>) firstArg;
        }
        return type;
    }

    /**
     * Instantiate a class by no-arg constructor, throw {@link ConfigurationException} if we fail to do so
     */
    @CoverageIgnore
    public static <T> T newInstance(Class<T> theType) {
        Validate.notNull(theType, "theType must not be null");
        try {
            return theType.newInstance();
        } catch (Exception e) {
            throw new ConfigurationException("Failed to instantiate " + theType.getName(), e);
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T newInstanceOrReturnNull(String theClassName, Class<T> theType) {
        try {
            Class<?> clazz = Class.forName(theClassName);
            if (!theType.isAssignableFrom(clazz)) {
                throw new ConfigurationException(theClassName + " is not assignable to " + theType);
            }
            return (T) clazz.newInstance();
        } catch (ConfigurationException e) {
            throw e;
        } catch (Exception e) {
            ourLog.info("Failed to instantiate {}: {}", theClassName, e.toString());
            return null;
        }
    }

    public static boolean isInstantiable(Class<?> theType) {
        return !theType.isInterface() && !Modifier.isAbstract(theType.getModifiers());
    }

}