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

tech.pardus.utilities.ReflectionUtils Maven / Gradle / Ivy

There is a newer version: 0.0.12
Show newest version
/**
 *
 */
package tech.pardus.utilities;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author deniz.toktay
 * @since Aug 20, 2020
 */
public class ReflectionUtils {

	private static final Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);

	private ReflectionUtils() {
	}

	/**
	 * @return main class of the app if there is any
	 * @throws ClassNotFoundException
	 */
	public static Class getMainClass() throws ClassNotFoundException {
		if (Objects.isNull(mainClass)) {
			var threadMap = Thread.getAllStackTraces();
			for (var entry : threadMap.entrySet()) {
				evaluateThreadElements(entry);
			}
		}
		return mainClass;
	}

	/**
	 * @param clazz (Type of target Class) (Type of target Class)
	 * @return initiated class object
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	public static Object initClass(Class clazz)
	        throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		return clazz.getConstructor().newInstance();
	}

	/**
	 * @param 
	 * @param clazz (Type of target Class)
	 * @return Set of classes which extends given Class
	 */
	public static  Set> listOfExtendedClasses(Class clazz) {
		var reflections = new Reflections(findPackageNames());
		return reflections.getSubTypesOf(clazz);
	}

	/**
	 * @param method
	 * @return true if method is static
	 */
	public static boolean isMethodStatic(Method method) {
		return Modifier.isStatic(method.getModifiers());
	}

	/**
	 * @param object
	 * @param methodName
	 * @param args
	 * @return method return after execution
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	public static Object runMethod(Object object, String methodName, Object... args)
	        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		Object result = null;
		var method = getMethod(object.getClass(), methodName);
		if (isMethodStatic(method)) {
			result = runStaticMethod(object.getClass(), methodName, args);
		} else {
			result = runJavaMethod(object, methodName, args);
		}
		return result;
	}

	/**
	 * @param clazz      (Type of target Class)
	 * @param methodName
	 * @return Get method of the given method name
	 * @throws NoSuchMethodException
	 */
	public static Method getMethod(Class clazz, String methodName) throws NoSuchMethodException {
		return clazz.getMethod(methodName);
	}

	/**
	 * @return Set of Package Names
	 */
	public static Set findPackageNames() {
		// @formatter:off
		Predicate notReservedPredicate = t -> isNotReserved(t);
		return Stream
			.of(Package.getPackages())
				.map(Package::getName)
				.filter(notReservedPredicate)
			.collect(Collectors.toSet());
		// @formatter:on
	}

	/**
	 * @param prefix
	 * @return set of package names starting with given prefix
	 */
	public static Set findPackageNamesStartingWith(String prefix) {
		// @formatter:off
		return Stream
				.of(Package.getPackages())
					.map(Package::getName)
					.filter(n -> n.startsWith(prefix))
		        .collect(Collectors.toSet());
		// @formatter:on
	}

	public static Set> getAllClassesAnnotatedWith(Class annotation) {
		var reflections = new Reflections(findPackageNames());
		return reflections.getTypesAnnotatedWith(annotation);
	}

	public static Set getAllMethodsAnnotatedWith(Class annotation) {
		var reflections = new Reflections(findPackageNames());
		return reflections.getMethodsAnnotatedWith(annotation);
	}

	public static Set getAllFieldsAnnotatedWith(Class annotation) {
		var reflections = new Reflections(findPackageNames());
		return reflections.getFieldsAnnotatedWith(annotation);
	}


	private static Object runJavaMethod(Object object, String methodName, Object... args)
	        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		Object result = null;
		var method = getMethod(object.getClass(), methodName);
		result = method.invoke(object, args);
		return result;
	}

	private static Object runStaticMethod(Class clazz, String methodName, Object... args)
	        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		var method = getMethod(clazz, methodName);
		return method.invoke(null, args);
	}

	private static void evaluateThreadElements(Entry entry) throws ClassNotFoundException {
		for (var element : entry.getValue()) {
			try {
				var stackClass = element.getClassName();
				if (StringUtils.isNotBlank(stackClass) && StringUtils.contains(stackClass, "$")) {
					stackClass = StringUtils.substring(stackClass, 0, StringUtils.lastIndexOf(stackClass, "$"));
				}
				if (isNotReserved(stackClass)) {
					var instance = Class.forName(stackClass);
					var method = instance.getDeclaredMethod("main", String[].class);
					if (Objects.nonNull(method) && Modifier.isStatic(method.getModifiers())) {
						mainClass = instance;
					}
				}
			} catch (NoSuchMethodException e) {
				logger.trace("Searching Main Class");
			}
		}
	}
	// @formatter:off

	private static Set getReservedClasses(){
		if (CollectionUtils.isEmpty(reservedClasses)) {
			reservedClasses = new HashSet();
			try(var bufferedReader = new BufferedReader(new InputStreamReader(ReflectionUtils.class.getClassLoader().getResourceAsStream("excluded_packet_initials")))){
				while (bufferedReader.ready()) {
					var line = bufferedReader.readLine();
					reservedClasses.add(line.strip());
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return reservedClasses;
	}
	private static Set reservedClasses;
	// @formatter:on

	private static boolean isNotReserved(String name) {
		var control = getReservedClasses().stream().filter(t -> StringUtils.startsWith(name, t)).findFirst()
		        .map(x -> Boolean.FALSE).orElse(Boolean.TRUE);
		return control.booleanValue();
	}

	private static Class mainClass;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy