package org.test4j.datafilling.filler; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Map; import org.test4j.datafilling.Filler; import org.test4j.datafilling.annotations.FillList; import org.test4j.datafilling.common.AttributeInfo; import org.test4j.datafilling.common.FillingConstants; import org.test4j.datafilling.strategy.AttributeStrategy; import org.test4j.datafilling.strategy.DataFactory; import org.test4j.datafilling.strategy.EmptyStrategy; import org.test4j.module.core.utility.MessageHelper; @SuppressWarnings("rawtypes") public class ArrayFiller extends Filler { public ArrayFiller(DataFactory strategy, Map<String, Type> argsTypeMap) { super(strategy, argsTypeMap); } private FillList getFilling(AttributeInfo attribute) { for (Annotation annotation : attribute.getAttrAnnotations()) { if (FillList.class.isAssignableFrom(annotation.getClass())) { FillList filling = (FillList) annotation; return filling; } } return null; } /** * It returns an Array with the first element set * * @param attribute The array type * @return Array with the first element set * @throws Exception */ public Object fillingArray(AttributeInfo attribute) throws Exception { int nbrElements = FillingConstants.ARRAY_DEFAULT_SIZE; FillList filling = this.getFilling(attribute); AttributeStrategy elementStrategy = null; if (null != filling) { nbrElements = filling.size(); elementStrategy = filling.collectionElementStrategy().newInstance(); } return createArrayInstance(attribute, nbrElements, filling, elementStrategy); } private Object createArrayInstance(AttributeInfo attribute, int nbrElements, FillList filling, AttributeStrategy elementStrategy) throws Exception { AttributeInfo itemAttribute = getArrayItemAttribute(attribute); itemAttribute.setAttrAnnotations(attribute.getAttrAnnotations()); Object array = Array.newInstance(itemAttribute.getAttrClaz(), nbrElements); for (int i = 0; i < nbrElements; i++) { Object arrayElement = createArrayItem(itemAttribute, filling, elementStrategy); Array.set(array, i, arrayElement); } return array; } /** * 获取数组项的具体属性类型 * * @param arrayAttribute * @param typeArgsMap * @return */ private AttributeInfo getArrayItemAttribute(AttributeInfo arrayAttribute) { Class itemClaz = arrayAttribute.getComponentType(); AttributeInfo ainfo = new AttributeInfo(itemClaz); Type[] genericTypeArgs = new Type[] {}; try { final Type genericType = arrayAttribute.getDeclaredField().getGenericType(); if (!(genericType instanceof GenericArrayType)) { return ainfo; } final Type type = ((GenericArrayType) genericType).getGenericComponentType(); if (!(type instanceof TypeVariable)) { return ainfo; } final Type typeVarType = argsTypeMap.get(((TypeVariable) type).getName()); if (typeVarType instanceof ParameterizedType) { final ParameterizedType pType = (ParameterizedType) typeVarType; itemClaz = (Class) pType.getRawType(); genericTypeArgs = pType.getActualTypeArguments(); } else { itemClaz = (Class) typeVarType; } } catch (NoSuchFieldException e) { MessageHelper.info("Cannot get the declared field type for field " + arrayAttribute.getAttrName() + " of class " + arrayAttribute.getPoJoName()); } ainfo = new AttributeInfo(itemClaz).setAttrArgs(genericTypeArgs); return ainfo; } private Object createArrayItem(AttributeInfo componentType, FillList filling, AttributeStrategy elementStrategy) throws Exception { if (null != elementStrategy && EmptyStrategy.class.isAssignableFrom(filling.collectionElementStrategy()) && componentType.isObject()) { return elementStrategy.getValue(); } else if (null != elementStrategy && !EmptyStrategy.class.isAssignableFrom(filling.collectionElementStrategy())) { return returnAttributeDataStrategyValue(componentType.getAttrClaz(), elementStrategy); } else { Object arrayElement = filling(this.strategy, componentType); return arrayElement; } } }