final SetPropertiesTemplatedFile body = new SetPropertiesTemplatedFile();
body.setBean(beanType);
final NewType factoryBean = bean.getFactoryBean();
final Method method = factoryBean.getMostDerivedMethod(Constants.SATISFY_PROPERTIES, this.getParameterListWithOnlyObject());
final NewMethod newMethod = method.copy(factoryBean);
newMethod.setAbstract(false);
newMethod.setFinal(true);
newMethod.setNative(false);
final NewMethodParameter instanceParameter = (NewMethodParameter) newMethod.getParameters().get(0);
instanceParameter.setFinal(true);
instanceParameter.setName(Constants.SATISFY_PROPERTIES_INSTANCE_PARAMETER);
newMethod.setBody(body);
// loop thru all properties
final Set<Property> properties = bean.getProperties();
final Iterator<Property> propertyIterator = properties.iterator();
while (propertyIterator.hasNext()) {
final Property property = propertyIterator.next();
final String propertyName = property.getName();
final String setterName = GeneratorHelper.buildSetterName(propertyName);
final Value value = property.getValue();
this.prepareValue(value);
final List<Method> matchingSetters = new ArrayList<Method>();
final VirtualMethodVisitor visitor = new VirtualMethodVisitor() {
protected boolean visit(final Method method) {
while (true) {
// names dont match
if (false == method.getName().equals(setterName)) {
break;
}
// return type must be void
if (false == method.getReturnType().equals(voidType)) {
break;
}
// parameter types must be compatible...
final List<MethodParameter> parameters = method.getParameters();
if (parameters.size() != 1) {
break;
}
final MethodParameter parameter = (MethodParameter) parameters.get(0);
final Type propertyType = parameter.getType();
if (false == value.isCompatibleWith(propertyType)) {
break;
}
value.setPropertyType(propertyType);
matchingSetters.add(method);
break;
}
return false;
}
protected boolean skipJavaLangObjectMethods() {
return true;
}
};
visitor.start(beanType);
if (matchingSetters.isEmpty()) {
this.throwUnableToFindSetter(bean, property);
}
if (matchingSetters.size() != 1) {
this.throwTooManySettersFound(bean, property);
}
final Method setter = (Method) matchingSetters.get(0);
body.addProperty(setter, value);
context.debug(propertyName + "=" + value);
}
}