*/
Set<FieldMap> fields = new HashSet<FieldMap>(classMap.getFieldsMapping());
for (String arg: declaredParameterNames) {
Iterator<FieldMap> iter = fields.iterator();
while(iter.hasNext()) {
FieldMap fieldMap = iter.next();
if (!fieldMap.is(aMappingOfTheRequiredClassProperty())) {
if ( !aToB) {
fieldMap = fieldMap.flip();
}
if (fieldMap.getSource().getName().equals(arg)) {
targetParameters.put(arg, fieldMap);
iter.remove();
}
}
}
}
} else {
/*
* Determine the set of constructor argument names
* from the field mapping
*/
for(FieldMap fieldMap: classMap.getFieldsMapping()) {
if (!fieldMap.is(aMappingOfTheRequiredClassProperty())) {
if (!aToB) {
fieldMap = fieldMap.flip();
}
targetParameters.put(fieldMap.getDestination().getName(), fieldMap);
}
}
}
Constructor<T>[] constructors = (Constructor<T>[]) targetClass.getRawType().getConstructors();
TreeMap<Integer, ConstructorMapping<T>> constructorsByMatchedParams = new TreeMap<Integer, ConstructorMapping<T>>();
for (Constructor<T> constructor: constructors) {
ConstructorMapping<T> constructorMapping = new ConstructorMapping<T>();
constructorMapping.setDeclaredParameters(declaredParameterNames);
boolean byDefault = declaredParameterNames == null;
try {
/*
* 1) A constructor's parameters are all matched by known parameter names
* 2) ...
*/
String[] parameterNames = paranamer.lookupParameterNames(constructor);
java.lang.reflect.Type[] genericParameterTypes = constructor.getGenericParameterTypes();
Type<?>[] parameterTypes = new Type[genericParameterTypes.length];
constructorMapping.setParameterNameInfoAvailable(true);
if (targetParameters.keySet().containsAll(Arrays.asList(parameterNames))) {
constructorMapping.setConstructor(constructor);
for (int i=0; i < parameterNames.length; ++i) {
String parameterName = parameterNames[i];
parameterTypes[i] = TypeFactory.valueOf(genericParameterTypes[i]);
FieldMap existingField = targetParameters.get(parameterName);
FieldMap argumentMap = mapConstructorArgument(existingField, parameterTypes[i], byDefault);
constructorMapping.getMappedFields().add(argumentMap);
}
constructorMapping.setParameterTypes(parameterTypes);
constructorsByMatchedParams.put(parameterNames.length*1000, constructorMapping);
}
} catch (ParameterNamesNotFoundException e) {
/*
* Could not find parameter names of the constructors; attempt to match constructors
* based on the types of the destination properties
*/
List<FieldMap> targetTypes = new ArrayList<FieldMap>(targetParameters.values());
int matchScore = 0;
int exactMatches = 0;
java.lang.reflect.Type[] params = constructor.getGenericParameterTypes();
Type<?>[] parameterTypes = new Type[params.length];
for (int i=0; i < params.length; ++i) {
java.lang.reflect.Type param = params[i];
parameterTypes[i] = TypeFactory.valueOf(param);
for (Iterator<FieldMap> iter = targetTypes.iterator(); iter.hasNext();) {
FieldMap fieldMap = iter.next();
Type<?> targetType = fieldMap.getDestination().getType();
if ((parameterTypes[i].equals(targetType) && ++exactMatches != 0)
|| parameterTypes[i].isAssignableFrom(targetType) ) {
++matchScore;
String parameterName = fieldMap.getDestination().getName();
FieldMap existingField = targetParameters.get(parameterName);
FieldMap argumentMap = mapConstructorArgument(existingField, parameterTypes[i], byDefault);
constructorMapping.getMappedFields().add(argumentMap);
iter.remove();
break;
}