All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.querydsl.core.util.ReflectionUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
 *
 * 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.querydsl.core.util;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
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.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import org.jetbrains.annotations.Nullable;

/**
 * ReflectionUtils provides Reflection related functionality
 *
 * @author tiwe
 */
public final class ReflectionUtils {

  private static final AnnotatedElement EMPTY = new Annotations();

  private ReflectionUtils() {}

  public static AnnotatedElement getAnnotatedElement(
      Class beanClass, String propertyName, Class propertyClass) {
    Field field = getFieldOrNull(beanClass, propertyName);
    Method method = getGetterOrNull(beanClass, propertyName, propertyClass);
    if (field == null || field.getAnnotations().length == 0) {
      return (method != null && method.getAnnotations().length > 0) ? method : EMPTY;
    } else if (method == null || method.getAnnotations().length == 0) {
      return field;
    } else {
      return new Annotations(field, method);
    }
  }

  @Nullable
  public static Field getFieldOrNull(Class beanClass, String propertyName) {
    while (beanClass != null && !beanClass.equals(Object.class)) {
      try {
        return beanClass.getDeclaredField(propertyName);
      } catch (SecurityException | NoSuchFieldException e) {
        // skip
      }
      beanClass = beanClass.getSuperclass();
    }
    return null;
  }

  @Nullable
  public static Method getGetterOrNull(Class beanClass, String name) {
    Method method = getGetterOrNull(beanClass, name, Object.class);
    if (method != null) {
      return method;
    } else {
      return getGetterOrNull(beanClass, name, Boolean.class);
    }
  }

  @Nullable
  public static Method getGetterOrNull(Class beanClass, String name, Class type) {
    var methodName =
        ((type.equals(Boolean.class) || type.equals(boolean.class)) ? "is" : "get")
            + BeanUtils.capitalize(name);
    while (beanClass != null && !beanClass.equals(Object.class)) {
      try {
        return beanClass.getDeclaredMethod(methodName);
      } catch (SecurityException | NoSuchMethodException e) { // skip
      }
      beanClass = beanClass.getSuperclass();
    }
    return null;
  }

  public static int getTypeParameterCount(java.lang.reflect.Type type) {
    if (type instanceof ParameterizedType) {
      return ((ParameterizedType) type).getActualTypeArguments().length;
    } else if (type instanceof TypeVariable) {
      return getTypeParameterCount(((TypeVariable) type).getBounds()[0]);
    } else {
      return 0;
    }
  }

  public static Class getTypeParameterAsClass(java.lang.reflect.Type type, int index) {
    Type parameter = getTypeParameter(type, index);
    if (parameter != null) {
      return asClass(parameter);
    } else {
      return null;
    }
  }

  @Nullable
  public static Type getTypeParameter(java.lang.reflect.Type type, int index) {
    if (type instanceof ParameterizedType) {
      return ((ParameterizedType) type).getActualTypeArguments()[index];
    } else if (type instanceof TypeVariable) {
      return getTypeParameter(((TypeVariable) type).getBounds()[0], index);
    } else {
      return null;
    }
  }

  private static Class asClass(Type type) {
    if (type instanceof WildcardType) {
      var wildcardType = (WildcardType) type;
      if (wildcardType.getUpperBounds()[0] instanceof Class) {
        return (Class) wildcardType.getUpperBounds()[0];
      } else if (wildcardType.getUpperBounds()[0] instanceof ParameterizedType) {
        return (Class) ((ParameterizedType) wildcardType.getUpperBounds()[0]).getRawType();
      } else {
        return Object.class;
      }
    } else if (type instanceof TypeVariable) {
      return asClass(((TypeVariable) type).getBounds()[0]);
    } else if (type instanceof ParameterizedType) {
      return (Class) ((ParameterizedType) type).getRawType();
    } else if (type instanceof GenericArrayType) {
      var component = ((GenericArrayType) type).getGenericComponentType();
      return Array.newInstance(asClass(component), 0).getClass();
    } else if (type instanceof Class) {
      return (Class) type;
    } else {
      throw new IllegalArgumentException(type.getClass().toString());
    }
  }

  public static Set> getSuperClasses(Class cl) {
    Set> classes = new HashSet<>();
    Class c = cl;
    while (c != null) {
      classes.add(c);
      c = c.getSuperclass();
    }
    return classes;
  }

  public static Set getFields(Class cl) {
    Set fields = new HashSet<>();
    Class c = cl;
    while (c != null) {
      fields.addAll(Arrays.asList(c.getDeclaredFields()));
      c = c.getSuperclass();
    }
    return fields;
  }

  public static Set> getImplementedInterfaces(Class cl) {
    Set> interfaces = new HashSet<>();
    Deque> classes = new ArrayDeque<>();
    classes.add(cl);
    while (!classes.isEmpty()) {
      Class c = classes.pop();
      interfaces.addAll(Arrays.asList(c.getInterfaces()));
      if (c.getSuperclass() != null) {
        classes.add(c.getSuperclass());
      }
      classes.addAll(Arrays.asList(c.getInterfaces()));
    }
    return interfaces;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy