mtedone / podam

PODAM - POjo DAta Mocker
https://mtedone.github.io/podam
MIT License
323 stars 750 forks source link

attributeMetadata.getAttributeName() is not returning the field name on Inmutable Objects #306

Closed danipenaperez closed 2 years ago

danipenaperez commented 2 years ago

Using inmutable objects (only constructor +getters ) there is no simple way to use a AbstractTypeManufacturer implementation to detect the current fieldName (attributeMetadata.getAttributeName()) to customize value population.

If the Pojo Class does not contains a Setter method for a value the method attributeMetadata.getAttributeName() returns the index property at constructor (plus constructor used info).

Reproduce: Pojo inmutable class:

@Getter
@AllArgsConstructor
public class MyPojo {
    private Long id;
    private String name;
    private String observations;
}

Try to intercept the name field to customize

class CustomStringManufacturer extends StringTypeManufacturerImpl {

    private static final String FIELD_ID = "observations";

    @Override
    public String getType(final DataProviderStrategy strategy, final AttributeMetadata attributeMetadata,
                          final Map<String, Type> genericTypesArgumentsMap) {
        if (FIELD_ID.equals(attributeMetadata.getAttributeName())) {  //This fields never match
            return "MyCustomValue";
        }
        return super.getType(strategy, attributeMetadata, genericTypesArgumentsMap);
    };

}
....
....
//regsiter at factory
podamFactory.getStrategy().addOrReplaceTypeManufacturer(String.class, new CustomStringManufacturer());

The if clause never matchs because attributeMetadata.getAttributeName() returns:

2[class java.lang.Long, class java.lang.String, class java.lang.String]

daivanov commented 2 years ago

Hi,

Java doesn't store arguments names in java code, so there is no way we can match constructor arguments with fields. You have to match them by id or create a setter, or annotate constructor parameters.

Thanks, Daniil

daivanov commented 2 years ago

And even more to this, constructor argument names not necessary match names of the fields, especially if constructor is auto-generated like in your case.

Thanks, Daniil