j-easy / easy-random

The simple, stupid random Java beans/records generator
https://github.com/j-easy/easy-random/wiki
MIT License
1.61k stars 233 forks source link

How RegistriesRandomizerProvider works? #517

Open metalpalo opened 1 month ago

metalpalo commented 1 month ago

Hi, Im trying to implement custom RandomizerRegistry with low priority(e.g -100) in order to check if class contains builder() method. If so construct relevant Builder class(generated by Immutable project), then populate fields within Buider class with internal EasyRandom and finally call his build() method to return original requested class to be randomized.

Everything is implemented via java reflection and it seems that works but what I found is that RegistriesRandomizerProvider goes accross all registries to check if any randomizer exists. And then returns first one.

My problem is that my registry class is always checked also when for instance String field is incoming and it could cause performance issues.

My question is why following method always evaluate all registries and not stop when first one if found?

private Randomizer<?> getRandomizer(final Provider provider) {
        return registries.stream()//it should be already sorted by priority
                .map(provider::getRandomizer)//it always goes for each registered registry, why not to stop loop when first one is found?
                .filter(Objects::nonNull)
                .sorted(priorityComparator) //what does it mean, we sort all found randomizers
                .findFirst().orElse(null);
    }

thanks

trinhnx commented 1 month ago

@metalpalo The reason the registries are all evaluated because sorted operation, you may need to process all list items just to apply the sorted. Your point is totally valid, because the registries already sorted when added new one.

metalpalo commented 1 month ago

@trinhnx thanks for response, I good understand, evaluation all registries are necessary right?. If so then we need to define priority on Randomizer classes too? Otherwise I dont see sense from my side

I put my custom user registry into parameters before EasyRandom construction, so everyting should be sorted within constructor. I dont see option that user registry can be added later through parameters and change is automatically taken into account.

Another question: As mentioned I implemented custom registry to check if class, interface contains builder() method(comming from Immutables) framework, if given method exists I call it to construct Builder class then I want to populate fields via EasyRandom instance. So I create singleton instance if EasyRandom again and call nextObject. I dont have access to doPolulateBean method(package private). I would like to prefer it due to go in identical RandomizerContext but when looking at RegistriesRandomizerProvider context are not used. But my randomizer could implement ContextAwareRandomizer right? What can I do in order to call doPopulateBean method instead doNext() one. I need to create subclass in identical package? I would like to prefer on EasyRandom instance with correct context(not creating new one via nextObject method)

thanks