
io.github.benas.randombeans.util.ReflectionUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of random-beans Show documentation
Show all versions of random-beans Show documentation
Random Beans core implementation
/*
* The MIT License
*
* Copyright (c) 2016, Mahmoud Ben Hassine ([email protected])
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package io.github.benas.randombeans.util;
import lombok.experimental.UtilityClass;
import java.lang.reflect.*;
import java.util.*;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
/**
* Reflection utility methods.
*
* @author Mahmoud Ben Hassine ([email protected])
*/
@UtilityClass
public class ReflectionUtils {
/**
* Get declared fields of a given type.
*
* @param type the type to introspect
* @return list of declared fields
*/
public static List getDeclaredFields(T type) {
return new ArrayList<>(asList(type.getClass().getDeclaredFields()));
}
/**
* Get inherited fields of a given type.
*
* @param type the type to introspect
* @return list of inherited fields
*/
public static List getInheritedFields(Class> type) {
List inheritedFields = new ArrayList<>();
while (type.getSuperclass() != null) {
Class> superclass = type.getSuperclass();
inheritedFields.addAll(asList(superclass.getDeclaredFields()));
type = superclass;
}
return inheritedFields;
}
/**
* Set a value (accessible or not accessible) in a field of a target object.
*
* @param object instance to set the property on
* @param field field to set the property on
* @param value value to set
* @throws IllegalAccessException if the property cannot be set
*/
public static void setProperty(final Object object, final Field field, final Object value) throws IllegalAccessException {
boolean access = field.isAccessible();
field.setAccessible(true);
field.set(object, value);
field.setAccessible(access);
}
/**
* Check if a field is static.
*
* @param field the field to check
* @return true if the field is static, false otherwise
*/
public static boolean isStatic(final Field field) {
return Modifier.isStatic(field.getModifiers());
}
/**
* Check if a type is an interface.
*
* @param type the type to check
* @return true if the type is an interface, false otherwise
*/
public static boolean isInterface(final Class> type) {
return type.isInterface();
}
/**
* Check if the type is abstract (either an interface or an abstract class).
*
* @param type the type to check
* @return true if the type is abstract, false otherwise
*/
public static boolean isAbstract(final Class type) {
return Modifier.isAbstract(type.getModifiers());
}
/**
* Check if the type is public.
*
* @param type the type to check
* @return true if the type is public, false otherwise
*/
public static boolean isPublic(final Class type) {
return Modifier.isPublic(type.getModifiers());
}
/**
* Check if a type is an array type.
*
* @param type the type to check.
* @return true if the type is an array type, false otherwise.
*/
public static boolean isArrayType(final Class> type) {
return type.isArray();
}
/**
* Check if a type is an enum type.
*
* @param type the type to check.
* @return true if the type is an enum type, false otherwise.
*/
public static boolean isEnumType(final Class> type) {
return type.isEnum();
}
/**
* Check if a type is a collection type.
*
* @param type the type to check.
* @return true if the type is a collection type, false otherwise
*/
public static boolean isCollectionType(final Class> type) {
return Collection.class.isAssignableFrom(type);
}
/**
* Check if a type is a collection type.
*
* @param type the type to check.
* @return true if the type is a collection type, false otherwise
*/
public static boolean isCollectionType(final Type type) {
return isParameterizedType(type) && isCollectionType((Class>) ((ParameterizedType) type).getRawType());
}
/**
* Check if a type is populatable.
*
* @param type the type to check
* @return true if the type is populatable, false otherwise
*/
public static boolean isPopulatable(final Type type) {
return !isWildcardType(type) && !isCollectionType(type);
}
/**
* Check if a type should be introspected for internal fields.
*
* @param type the type to check
* @return true if the type should be introspected, false otherwise
*/
public static boolean isIntrospectable(final Class> type) {
return !isEnumType(type)
&& !isArrayType(type)
&& !(isCollectionType(type) && isJdkBuiltIn(type))
&& !(isMapType(type) && isJdkBuiltIn(type));
}
/**
* Check if a type is a map type.
*
* @param type the type to check
* @return true if the type is a map type, false otherwise.
*/
public static boolean isMapType(final Class> type) {
return Map.class.isAssignableFrom(type);
}
/**
* Check if a type is a JDK built-in collection/map.
*
* @param type the type to check
* @return true if the type is a built-in collection/map type, false otherwise.
*/
public static boolean isJdkBuiltIn(final Class> type) {
return type.getName().startsWith("java.util");
}
/**
* Check if a type is a parameterized type
*
* @param type the type to check
* @return true if the type is parameterized, false otherwise
*/
public static boolean isParameterizedType(final Type type) {
return type != null && type instanceof ParameterizedType && ((ParameterizedType) type).getActualTypeArguments().length > 0;
}
/**
* Check if a type is a wildcard type
*
* @param type the type to check
* @return true if the type is a wildcard type, false otherwise
*/
public static boolean isWildcardType(final Type type) {
return type instanceof WildcardType;
}
/**
* Searches the classpath for all public concrete subtypes of the given interface or abstract class.
*
* @param type to search concrete subtypes of
* @return a list of all concrete subtypes found
*/
public static List> getPublicConcreteSubTypesOf(final Class type) {
return FastClasspathScannerFacade.getPublicConcreteSubTypesOf(type);
}
/**
* Filters a list of types to keep only elements having the same parameterized types as the given type.
*
* @param type the type to use for the search
* @param types a list of types to filter
* @return a list of types having the same parameterized types as the given type
*/
public static List> filterSameParameterizedTypes(final List> types, final Type type) {
if (type instanceof ParameterizedType) {
Type[] fieldArugmentTypes = ((ParameterizedType) type).getActualTypeArguments();
List> typesWithSameParameterizedTypes = new ArrayList<>();
for (Class> currentConcreteType : types) {
List actualTypeArguments = getActualTypeArgumentsOfGenericInterfaces(currentConcreteType);
typesWithSameParameterizedTypes.addAll(actualTypeArguments.stream().filter(currentTypeArguments -> Arrays.equals(fieldArugmentTypes, currentTypeArguments)).map(currentTypeArguments -> currentConcreteType).collect(toList()));
}
return typesWithSameParameterizedTypes;
}
return types;
}
private static List getActualTypeArgumentsOfGenericInterfaces(final Class> type) {
List actualTypeArguments = new ArrayList<>();
Type[] genericInterfaceTypes = type.getGenericInterfaces();
for (Type currentGenericInterfaceType : genericInterfaceTypes) {
if (currentGenericInterfaceType instanceof ParameterizedType) {
actualTypeArguments.add(((ParameterizedType) currentGenericInterfaceType).getActualTypeArguments());
}
}
return actualTypeArguments;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy