package de.flower.common.test.wicket; import de.flower.common.util.ReflectionUtil; import org.apache.wicket.Application; import org.apache.wicket.MetaDataKey; import org.apache.wicket.injection.IFieldValueFactory; import org.apache.wicket.spring.ISpringContextLocator; import org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory; import org.apache.wicket.spring.injection.annot.SpringComponentInjector; import org.springframework.context.ApplicationContext; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; /** * Resets all previously injected beans. * Simulates DirtiesContext.AFTER_METHOD. * Required cause Mockito.reset() does not fully reset mocks. * * @author flowerrrr */ public class SpringComponentInjectorUtils { public static void resetAllBeans(Object object, final SpringComponentInjector injector) { final IFieldValueFactory fieldValueFactory = new AnnotProxyFieldValueFactory(new ContextLocator(injector), false); Field[] fields = findFields(object.getClass(), fieldValueFactory); for (final Field field : fields) { if (!field.isAccessible()) { field.setAccessible(true); } try { if (field.get(object) != null) { field.set(object, null); } } catch (Exception e) { throw new RuntimeException(e); } } } /** * Copied from org.apache.wicket.injection.Injector#findFields(java.lang.Class<?>, org.apache.wicket.injection.IFieldValueFactory). * @param clazz * @param factory * @return */ private static Field[] findFields(Class<?> clazz, final IFieldValueFactory factory) { List<Field> matched = new ArrayList<Field>(); while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (final Field field : fields) { if (factory.supportsField(field)) { matched.add(field); } } clazz = clazz.getSuperclass(); } return matched.toArray(new Field[matched.size()]); } /** * Copied from org.apache.wicket.spring.injection.annot.SpringComponentInjector.ContextLocator. */ private static class ContextLocator implements ISpringContextLocator { private transient ApplicationContext context; private static final long serialVersionUID = 1L; private SpringComponentInjector injector; public ContextLocator(final SpringComponentInjector injector) { this.injector = injector; } public ApplicationContext getSpringContext() { if (context == null) { MetaDataKey<ApplicationContext> contextKey = (MetaDataKey<ApplicationContext>) ReflectionUtil.getField(injector, "CONTEXT_KEY"); context = Application.get().getMetaData(contextKey); } return context; } } }