package org.test4j.datafilling.filler.pojo; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Type; import java.util.Arrays; import java.util.List; import java.util.Map; import org.test4j.datafilling.Filler; import org.test4j.datafilling.common.AttributeInfo; import org.test4j.datafilling.filler.PoJoFiller; import org.test4j.datafilling.strategy.DataFactory; import org.test4j.module.core.utility.MessageHelper; import org.test4j.tools.commons.Reflector; @SuppressWarnings({ "rawtypes", "unchecked" }) public class ConstructorFiller extends PoJoFiller { public ConstructorFiller(DataFactory strategy, Map<String, Type> argsTypeMap) { super(strategy, argsTypeMap); } /** * There are public constructors. We need the no-arg one for now. * * @param constructors * @param genericTypeArgs * @return */ public Object fillingWithPublicConstructor(Class clazz, Constructor[] constructors) { for (Constructor constructor : constructors) { try { Object[] constructorArgs = getParametersForConstructor(clazz, constructor); Object retValue = constructor.newInstance(constructorArgs); return retValue; } catch (Exception e) { String error = "Couldn't create attribute with constructor: " + constructor + ". Will check if other constructors are available"; MessageHelper.error(error, e); } } return null; } /** * Given a constructor it manufactures and returns the parameter values * required to invoke it * * @param clazz The POJO class containing the constructor * @param constructor The constructor for which parameter values are * required * @param typeArgsMap The generic type arguments for the current generic * class instance * @return The parameter values required to invoke the constructor * @throws Exception */ private Object[] getParametersForConstructor(Class clazz, Constructor constructor) throws Exception { Annotation[][] parameterAnnotations = constructor.getParameterAnnotations(); Class[] parameterTypes = constructor.getParameterTypes(); Object[] parameterValues = new Object[parameterTypes.length]; int index = 0; for (Class parameterType : parameterTypes) { if (parameterType.equals(clazz)) { parameterValues[index] = Reflector.instance.newInstance(clazz); } else { List<Annotation> annotations = Arrays.asList(parameterAnnotations[index]); Type paraGenType = constructor.getGenericParameterTypes()[index]; AttributeInfo paraAttribute = AttributeInfo.exactArgAttributeInfo(paraGenType, argsTypeMap); paraAttribute.setAttrAnnotations(annotations); Object para = new Filler(this.strategy, argsTypeMap).fillingAttribute(paraAttribute); parameterValues[index] = para; } index++; } return parameterValues; } }