Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bean property as array/list and inner beans #395

Open
gamerover98 opened this issue Nov 11, 2023 · 2 comments
Open

Bean property as array/list and inner beans #395

gamerover98 opened this issue Nov 11, 2023 · 2 comments
Milestone

Comments

@gamerover98
Copy link
Contributor

gamerover98 commented Nov 11, 2023

The problem
It is not easy to create a list or array of BeanProperty.
At the moment, I have found this solution:

@Getter @Setter // Lombok
public class Country implements ParameterizedType {

    private static final Type[] TYPE_ARGUMENTS = {
            String.class, // name type
            Integer.TYPE, // total population type
    };

    private String name;
    private int totalPopulation;
    ...

    @Override
    public Type[] getActualTypeArguments() {
        return TYPE_ARGUMENTS;
    }

    @Override
    public Type getRawType() {
        return ItemProperty.class;
    }

    @Override
    public Type getOwnerType() {
        return null;
    }
}
public static final Property<Country[]> COUNTRIES =
            new PropertyBuilder.ArrayPropertyBuilder<>(
                    new BeanPropertyType<>(
                            new TypeInformation(new Country()), DefaultMapper.getInstance()),
                    Country[]::new)
                    .path("country.list")
                    .defaultValue(new Country[0])
                    .build();

Now, if you want to add other info like a bean list called "City", it won't be serialized:

@Getter @Setter // Lombok
public class City implements ParameterizedType {

    private static final Type[] TYPE_ARGUMENTS = {
            String.class, // city type
            Integer.TYPE, // population type
    };

    private String name;
    private int population;
    ...
}
@Getter @Setter // Lombok
public class Country implements ParameterizedType {

    private static final Type[] TYPE_ARGUMENTS = {
            String.class, // name type
            Integer.TYPE, // total population type
            City[].class, // the city array type
    };

    private String name;
    private int totalPopulation;
    private City[] cities;
    ...
}

The YAML result will be:

country.list:
  - name: United States
    totalPopulation: 331000000
    cities: {}

But what I want is:

country.list:
  - name: United States
    totalPopulation: 331000000
    cities:
    - name: New York
      population: 8400000
    - name: Las Vegas
      population: 646700

A solution (?)
Maybe, define a BeanListProperty that extends ListPropery and grants an easy way to add beans without map field types.

@gamerover98
Copy link
Contributor Author

After conducting various tests, I have come to a conclusion. It is incorrect to serialize an array of Beans using the PropertyBuilder.ArrayPropertyBuilder(...) method. Instead, it is much easier to create a Bean class that encapsulates everything. Let me explain further by referring to the example of "Country":

The World Bean class:

@Getter @Setter
public class World {
    private List<Country> countries;
}

The property:

public static final Property<World> WORLD = 
            newBeanProperty(World.class, "world", new World());

@ljacqu
Copy link
Member

ljacqu commented Nov 13, 2023

This is probably the best solution since YAML sequences can look a bit weird without a property.

In ConfigMe 2.0, arrays or lists of a bean property type will become easier to maintain as ListPropertyType and ArrayPropertyType are based on an entry property type, which could be a bean property type (#230). I don't have any simple tests using a bean property so I might use this issue for adding some. Thanks!


Reminder not to implement ParameterizedType by yourself, as detailed in #354 (comment)

@ljacqu ljacqu added this to the 2.0.0 milestone Nov 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants