[JAVA-2554] Investigate Optional support for the Pojo Codec Created: 14/Jul/17  Updated: 29/Oct/23  Resolved: 04/Dec/17

Status: Closed
Project: Java Driver
Component/s: POJO
Affects Version/s: None
Fix Version/s: 3.6.0

Type: Improvement Priority: Major - P3
Reporter: Ross Lawley Assignee: Ross Lawley
Resolution: Fixed Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JAVA-4954 Refactor PojoCodec to leverage CodecP... Backlog

 Description   

PR: https://github.com/mongodb/mongo-java-driver/pull/418



 Comments   
Comment by Githook User [ 04/Dec/17 ]

Author:

{'username': 'jflorencio', 'email': 'joe@deal.com', 'name': 'Joseph Florencio'}

Message: Support for custom container types

While PojoCodec accounts for generic containers, it only
accounts for it when the PojoCodec is the one that encodes
and decodes it.

This doesn't work if you want to use Java 8 Optionals, or
other containers classes you don't have source code access to,
and can't be automatically serialized/deserialized.

To make this possible I introduced 4 changes to the public API:

  • `TypeWithTypeParameters`: This is an interface that `TypeData` now
    implements that exposes the captured type parameter data. The intention
    here was to reduce the surface area of the API exposed since TypeData
    has quite a bit going on, and I don't think we want to commit to such
    an API.
  • `PropertyCodecRegistry`: This is a new interface that's analogous to
    `CodecRegistry`, except instead of accepting a `Class<T>`, it accepts
    a `TypeWithTypeParameters<T>`. This is strictly for consumption by
    clients of the API - there is no expectation clients would implement
    it since it's provided through the property codec provider.
  • `PropertyCodecProvider`: Similar to above, this is anologous to
    `CodecProvider` except that it accepts a `TypeWithTypeParameters<T>` and
    a `PropertyCodecRegistry`. This is the primary interface that's
    implemented to support implementing custom containers like collections,
    maps, options, etc.
  • `PojoCodecProvider.Builder#register(PropertyCodecProvider...)`:
    How clients register the providers. Note that they cannot register a
    registry - this isn't as permissive as codec providers so it's
    intentionally constrained here.

Internally I shifted the implementation of enums, maps and collections to use
this new setup as well. You can see `CollectionPropertyCodecProvider`
and `MapPropertyCodecProvider` for how this looks - they're just
implicitly added to the same registration list clients use (see
`PojoCodecImpl.PropertyCodecRegistryImpl`).

In the tests I implemented `OptionalPropertyCodecProviderForTest` which
is a provider for a custom optional class, which gives an example for
people who would like to do the same, or support Java 8 optionals.

JAVA-2554
Branch: 3.6.x
https://github.com/mongodb/mongo-java-driver/commit/f525edfb09141b460b68ff7b974ae9099e0fa7fe

Comment by Ross Lawley [ 04/Dec/17 ]

A massive thank you to Joseph Florencio for the excellent pull request.

Comment by Githook User [ 04/Dec/17 ]

Author:

{'username': 'jflorencio', 'email': 'joe@deal.com', 'name': 'Joseph Florencio'}

Message: Support for custom container types

While PojoCodec accounts for generic containers, it only
accounts for it when the PojoCodec is the one that encodes
and decodes it.

This doesn't work if you want to use Java 8 Optionals, or
other containers classes you don't have source code access to,
and can't be automatically serialized/deserialized.

To make this possible I introduced 4 changes to the public API:

  • `TypeWithTypeParameters`: This is an interface that `TypeData` now
    implements that exposes the captured type parameter data. The intention
    here was to reduce the surface area of the API exposed since TypeData
    has quite a bit going on, and I don't think we want to commit to such
    an API.
  • `PropertyCodecRegistry`: This is a new interface that's analogous to
    `CodecRegistry`, except instead of accepting a `Class<T>`, it accepts
    a `TypeWithTypeParameters<T>`. This is strictly for consumption by
    clients of the API - there is no expectation clients would implement
    it since it's provided through the property codec provider.
  • `PropertyCodecProvider`: Similar to above, this is anologous to
    `CodecProvider` except that it accepts a `TypeWithTypeParameters<T>` and
    a `PropertyCodecRegistry`. This is the primary interface that's
    implemented to support implementing custom containers like collections,
    maps, options, etc.
  • `PojoCodecProvider.Builder#register(PropertyCodecProvider...)`:
    How clients register the providers. Note that they cannot register a
    registry - this isn't as permissive as codec providers so it's
    intentionally constrained here.

Internally I shifted the implementation of enums, maps and collections to use
this new setup as well. You can see `CollectionPropertyCodecProvider`
and `MapPropertyCodecProvider` for how this looks - they're just
implicitly added to the same registration list clients use (see
`PojoCodecImpl.PropertyCodecRegistryImpl`).

In the tests I implemented `OptionalPropertyCodecProviderForTest` which
is a provider for a custom optional class, which gives an example for
people who would like to do the same, or support Java 8 optionals.

JAVA-2554
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/f525edfb09141b460b68ff7b974ae9099e0fa7fe

Generated at Thu Feb 08 08:57:31 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.