Make APIs clearer about the fact automatic extractor resolution is an "all or nothing"

Description

Follow-up on HSEARCH-3438. We may want to do it before the release because it would impact the mapping API.

Currently users can write this:

1 2 3 4 5 @GenericField(extractors = { @ContainerExtractor(type = MyContainerExtractor1.class), @ContainerExtractor(BuiltinContainerExtractors.AUTOMATIC), @ContainerExtractor(type = MyContainerExtractor2.class) })

And it kind of makes sense, but it will fail at bootstrap, because AUTOMATIC can only be used if there is only one extractor.

We should improve the consistency between the API and the implementation: either we expose an API that does not even allow to express such things, or we change the implementation to support such things.

Solution 1: improve implementation

It shouldn't be too hard to support; the lower levels are probably ready, the main problem would be to modify ContainerExtractorPath to allow to represent the information (currently the whole path must represent "default extractors" (= automatic resolution), you can't model an automatic resolution mixed with explicit extractors.

However:

  1. It's really not clear what the use case for such an extractor chain would be. Why would you mention a few extractors explicitly, but use automatic resolution for the others?

  2. We would still have some inconsistency in the APIs: sometimes a @ContainerValue annotation would refer to one extractor (explicit reference) sometimes it would refer to zero, one or multiple extractors (automatic resolution)

Solution 2: restrict API

We could move up one level the place where automatic resolution is set, i.e.:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // Default: automatically resolved @GenericField // Explicit extractors @GenericField( extractorsResolvedFromType = false, extractors = { @ContainerExtractor(type = MyContainerExtractor1.class), @ContainerExtractor(type = MyContainerExtractor2.class) } ) // No extractor at all @GenericField( extractorsResolvedFromType = false, extractors = {} )

or:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // Default: automatically resolved @GenericField // Explicit extractors @GenericField(extraction = @ContainerExtraction( resolveFromType = false, value = { @ContainerExtractor(type = MyContainerExtractor1.class), @ContainerExtractor(type = MyContainerExtractor2.class) } )) // No extractor at all @GenericField(extraction = @ContainerExtraction( resolveFromType = false, value = {} ))

or:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public enum ContainerExtract { // If extractors are defined explicitly, apply those. Otherwise, automatically and recursively resolve extractors according to the type of the property (get elements for collections, values for maps, ...) DEFAULT, // Do not apply any extractor, and throw an exception if extractors are defined explicitly. NO; } // Default: automatically resolved @GenericField // Explicit extractors @GenericField(extraction = @ContainerExtraction({ @ContainerExtractor(type = MyContainerExtractor1.class), @ContainerExtractor(type = MyContainerExtractor2.class) }) // No extractor at all @GenericField(extraction = @ContainerExtraction(extract = ContainerExtract.NO))

or:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public enum ContainerExtraction { // If extractors are defined explicitly, apply those. Otherwise, automatically and recursively resolve extractors according to the type of the property (get elements for collections, values for maps, ...) DEFAULT, // Do not apply any extractor, and throw an exception if extractors are defined explicitly. NO; } // Default: automatically resolved @GenericField // Explicit extractors @GenericField( extractors = { @ContainerExtractor(type = MyContainerExtractor1.class), @ContainerExtractor(type = MyContainerExtractor2.class) } ) // No extractor at all @GenericField( extraction = ContainerExtraction.NO )

... but that's awfully verbose. Maybe the last one?

Other solutions?

I'd like other solutions, because the two above are not very satisfying.

Environment

None

Status

Assignee

Yoann Rodière

Reporter

Yoann Rodière

Labels

None

Suitable for new contributors

None

Feedback Requested

None

Components

Fix versions

Priority

Minor
Configure