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

net.jqwik.spring.JqwikSpringReflectionSupport Maven / Gradle / Ivy

The newest version!
package net.jqwik.spring;

import java.lang.reflect.*;
import java.util.*;

/**
 * This should somehow move to jqwik itself and be provided as a service to hooks
 *
 * TODO Remove as soon as jqwik provides this functionality
 */
class JqwikSpringReflectionSupport {

	interface Applier {
		void apply(Object instance) throws Exception;
	}

	static void applyToInstances(Object instance, Applier codeToApply) throws Exception {
		List instances = getInstances(instance);
		for (Object i : instances) {
			codeToApply.apply(i);
		}
	}

	private static List getInstances(Object instance) {
		return getInstances(instance, new ArrayList<>());
	}

	private static List getInstances(Object inner, List innerInstances) {
		Optional optionalOuter = getOuterInstance(inner);
		innerInstances.add(0, inner);
		return optionalOuter.map(outer -> getInstances(outer, innerInstances))
							.orElse(innerInstances);
	}

	// Copied from JqwikReflectionSupport
	private static Optional getOuterInstance(Object inner) {
		// This is risky since it depends on the name of the field which is nowhere guaranteed
		// but has been stable so far in all JDKs

		return Arrays
				   .stream(inner.getClass().getDeclaredFields())
				   .filter(field -> field.getName().startsWith("this$"))
				   .findFirst()
				   .map(field -> {
					   try {
						   return makeAccessible(field).get(inner);
					   } catch (SecurityException | IllegalArgumentException | IllegalAccessException ex) {
						   return Optional.empty();
					   }
				   });
	}

	// Copied from JqwikReflectionSupport
	private static  T makeAccessible(T object) {
		if (!object.isAccessible()) {
			object.setAccessible(true);
		}
		return object;
	}
}