Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
package br.com.six2six.fixturefactory.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.lang.reflect.*;
import java.util.*;

import net.vidageek.mirror.dsl.Mirror;
import net.vidageek.mirror.list.dsl.Matcher;
Expand All @@ -35,13 +28,19 @@ public static <T> T cast(Object source){
}

@SuppressWarnings("unchecked")
public static <T> T invokeGetter(Object bean, String attribute) {
return (T) ReflectionUtils.invokeGetter(bean, attribute, true);
public static <T> T invokeGetter(Object bean, String attribute, int collectionIndex) {
return (T) ReflectionUtils.invokeGetter(bean, attribute, collectionIndex, true);
}

@SuppressWarnings("unchecked")
public static <T> T invokeGetter(Object bean, String attribute, boolean fail) {
public static <T> T invokeGetter(Object bean, String attribute, int collectionIndex, boolean fail) {
try {
if(attribute.contains("[") && attribute.contains("]")) {
attribute = attribute.split("\\[")[0];
}
if(bean instanceof Collection) {
bean = ((Collection) bean).toArray()[collectionIndex];
}
return (T) getPropertyUtilsBean().getProperty(bean, attribute);
}catch (Exception e) {
if (fail) {
Expand All @@ -56,7 +55,7 @@ public static Object invokeRecursiveGetter(Object bean, String objectsPath) {
Object lastValue = null;
Object lastBean = bean;
for (String propertyItem : objectsPath.split("\\.")) {
lastValue = ReflectionUtils.invokeGetter(lastBean, propertyItem);
lastValue = ReflectionUtils.invokeGetter(lastBean, propertyItem, 0);
lastBean = lastValue;
if (lastValue == null) {
break;
Expand All @@ -65,8 +64,12 @@ public static Object invokeRecursiveGetter(Object bean, String objectsPath) {
return lastValue;
}

public static <T> void invokeSetter(Object bean, String attribute, Object value, boolean fail){
public static <T> void invokeSetter(Object bean, String attribute, Object value, int collectionIndex, boolean fail){
try {
if(bean instanceof Collection) {
Collection iterable = (Collection) bean;
bean = iterable.toArray()[collectionIndex];
}
new Mirror().on(bean).set().field(attribute).withValue(value);
} catch (Exception ex){
if(fail) {
Expand All @@ -76,11 +79,15 @@ public static <T> void invokeSetter(Object bean, String attribute, Object value,
}

public static <T> void invokeSetter(Object bean, String attribute, Object value){
ReflectionUtils.invokeSetter(bean, attribute, value, true);
ReflectionUtils.invokeSetter(bean, attribute, value, 0, true);
}

public static void invokeRecursiveSetter(Object bean, String attribute, Object value) {
ReflectionUtils.invokeSetter(prepareInvokeRecursiveSetter(bean, attribute, value), attribute.substring(attribute.lastIndexOf(".") + 1), value, true);
int collectionIndex = 0;
if(attribute.contains("[") && attribute.contains("]")) {
collectionIndex = Integer.parseInt(attribute.split("\\[")[1].split("\\]")[0]);
}
ReflectionUtils.invokeSetter(prepareInvokeRecursiveSetter(bean, attribute, value, collectionIndex), attribute.substring(attribute.lastIndexOf(".") + 1), value, collectionIndex, true);
}

public static Class<?> invokeRecursiveType(Class<?> clazz, String attribute) {
Expand All @@ -90,11 +97,21 @@ public static Class<?> invokeRecursiveType(Class<?> clazz, String attribute) {
public static Field invokeRecursiveField(Class<?> clazz, String attribute) {
Field field = null;
Class<?> targetBeanClass = getTargetClass(clazz);

for (String propertyItem : attribute.split("\\.")) {
if(propertyItem.contains("[") && propertyItem.contains("]")) {
propertyItem = propertyItem.split("\\[")[0];
}

field = new Mirror().on(targetBeanClass).reflect().field(propertyItem);
if (field == null) throw new IllegalArgumentException(String.format("%s-> Field %s doesn't exists", clazz.getName(), attribute));
targetBeanClass = field.getType();

if(Collection.class.isAssignableFrom(field.getType())){
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
targetBeanClass = (Class<?>) parameterizedType.getActualTypeArguments()[0];
} else {
targetBeanClass = field.getType();
}
}

return field;
Expand Down Expand Up @@ -165,7 +182,7 @@ public static PropertyUtilsBean getPropertyUtilsBean() {
return BeanUtilsBean.getInstance().getPropertyUtils();
}

private static Object prepareInvokeRecursiveSetter(Object bean, String attribute, Object value) {
private static Object prepareInvokeRecursiveSetter(Object bean, String attribute, Object value, int collectionIndex) {
Object targetBean = bean;
Object lastBean = null;

Expand All @@ -179,7 +196,7 @@ private static Object prepareInvokeRecursiveSetter(Object bean, String attribute
if (path != null) {
for (String propertyItem : path.split("\\.")) {
lastBean = targetBean;
targetBean = ReflectionUtils.invokeGetter(targetBean, propertyItem);
targetBean = ReflectionUtils.invokeGetter(targetBean, propertyItem, collectionIndex);
if(targetBean == null) {
Class<?> type = invokeRecursiveType(lastBean.getClass(), propertyItem);
try {
Expand All @@ -188,7 +205,7 @@ private static Object prepareInvokeRecursiveSetter(Object bean, String attribute
args.add(lastBean);
}
targetBean = newInstance(type, args);
ReflectionUtils.invokeSetter(lastBean, propertyItem, targetBean, true);
ReflectionUtils.invokeSetter(lastBean, propertyItem, targetBean, collectionIndex, true);
} catch (Exception e) {
throw new IllegalArgumentException(String.format(NO_SUCH_ATTRIBUTE_MESSAGE, lastBean.getClass().getName(), propertyItem, type.getName()));
}
Expand All @@ -213,7 +230,7 @@ public static <T,U> Collection<U> map(Collection<T> collection, String propertyN
}

for (T item : collection) {
map.add((U) ReflectionUtils.invokeGetter(item, propertyName, true));
map.add((U) ReflectionUtils.invokeGetter(item, propertyName, 0, true));
};
return map;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import java.util.List;

import br.com.six2six.fixturefactory.function.Function;
import br.com.six2six.fixturefactory.model.Address;
import org.junit.BeforeClass;
import org.junit.Test;

Expand All @@ -27,8 +29,30 @@ public void fixtureAnyStudent() {
assertNotNull("Students id should not be null", student.getId());
assertTrue("Tests taken should be greather than 0", student.getTestsTaken() > 0);
assertTrue("Best score should be greather than 0", student.getTestsTaken() > 0);
assertTrue("Addresses should be greather than 0", student.getAddresses().size() > 0);
}


@Test
public void fixtureStudentWithChangedAddresses() throws Exception {
Student student = Fixture.from(Student.class).gimme("valid", new Rule() {{
add("addresses[0].id", 123456L);
add("addresses[0].city.name", "BH");
add("addresses[0].city.neighborhoods[0].name", "Santa Efigênia");
add("addresses[1].id", 123457L);
add("addresses[2].id", 123458L);
}});

Address[] addresses = student
.getAddresses()
.toArray(new Address[student.getAddresses().size()]);

assertTrue(addresses[0].getId() == 123456L);
assertTrue(addresses[0].getCity().getName().equals("BH"));
assertTrue(addresses[0].getCity().getNeighborhoods().get(0).getName().equals("Santa Efigênia"));
assertTrue(addresses[1].getId() == 123457L);
assertTrue(addresses[2].getId() == 123458L);
}

@Test
public void fixtureFemaleStudent() {
Student student = Fixture.from(Student.class).gimme("validFemaleStudent");
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/br/com/six2six/template/StudentTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import br.com.six2six.fixturefactory.base.Sequence;
import br.com.six2six.fixturefactory.function.impl.NumberSequence;
import br.com.six2six.fixturefactory.loader.TemplateLoader;
import br.com.six2six.fixturefactory.model.Address;
import br.com.six2six.fixturefactory.model.Student;

public class StudentTemplate implements TemplateLoader {
Expand All @@ -20,6 +21,7 @@ public void load() {
add("bestScore", regex("\\d{2}\\.\\d{3}"));
add("testsTaken", regex("\\d{1}1"));
add("idCardNumber", regex("\\d{6}"));
add("addresses", has(3).of(Address.class, "valid"));
}}
).addTemplate("validFemaleStudent", new Rule(){{
add("id", sequence(200L, 2));
Expand Down