-
Notifications
You must be signed in to change notification settings - Fork 77
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
feat: add subtype module (2.17) #229
base: 2.16
Are you sure you want to change the base?
Conversation
@@ -33,6 +33,7 @@ not datatype, data format, or JAX-RS provider modules. | |||
<module>mrbean</module> | |||
<module>osgi</module> | |||
<module>paranamer</module> | |||
<module>subtype</module> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll probably want to change the name, "subtype" is too generic. But let me think about better name for a while...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a difficult thing for me to give it a name...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True🥲🥲
subtype/README.md
Outdated
Registering modules. | ||
|
||
``` | ||
ObjectMapper mapper = new ObjectMapper().registerModule(new DynamicSubtypeModule()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think current name is SubtypeModule
.
subtype/README.md
Outdated
2. provide a non-argument constructor (SPI require it). | ||
|
||
```java | ||
import io.github.black.jackson.JsonSubType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to change to new package.
@RunWith(value = Parameterized.class) | ||
public class WithJsonSubTypesTest<T extends WithJsonSubTypesTest.Parent> { | ||
|
||
private final ObjectMapper mapper = new ObjectMapper().findAndRegisterModules(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use this method but instead explicitly register module.
this.foo = foo; | ||
} | ||
|
||
@SuppressWarnings("unused") // jackson require it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could instead just use public String foo
to avoid having to add getter and setter
import static org.junit.Assert.assertTrue; | ||
|
||
/** | ||
* test work without {@link JsonSubTypes} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I understand -- why would we test functioning without module? And isn't module actually register with the mapper. Or what is being tested here? Could probably use longer explanation of reasoning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably test against Jackson polymorphic type handling working as expected. If so, does not seem necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually wanted to test whether @JsonSubType
worked with @JsonSubTypes
List<NamedType> list1 = SubtypeModule.findSubtypes(a.getRawType(), a::getAnnotation); | ||
List<NamedType> list2 = subtypes.getOrDefault(a.getRawType(), Collections.emptyList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename these list1
and list2
to something less generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (list1.isEmpty()) return list2; | ||
if (list2.isEmpty()) return list1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the two lists are null-safe, no need for empty checking.
List<NamedType> list = new ArrayList<>(list1.size() + list2.size()); | ||
list.addAll(list1); | ||
list.addAll(list2); | ||
return list; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List<NamedType> list = new ArrayList<>(list1.size() + list2.size()); | |
list.addAll(list1); | |
list.addAll(list2); | |
return list; | |
List<NamedType> list = new ArrayList<>(list1.size() + list2.size()); | |
list1.addAll(list2); | |
return list; |
List<NamedType> list = new ArrayList<>(list1.size() + list2.size()); | ||
list.addAll(list1); | ||
list.addAll(list2); | ||
return list; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to have duplication? If so, can we have these as set first, then return as list?
import static org.junit.Assert.assertTrue; | ||
|
||
/** | ||
* test work without {@link JsonSubTypes} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably test against Jackson polymorphic type handling working as expected. If so, does not seem necessary
subtypes.remove(parent); | ||
} | ||
|
||
private static <S> List<NamedType> findSubtypes(Class<S> clazz, Function<Class<JsonSubType>, JsonSubType> getter) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for keeping it static? if not maybe like...
private static <S> List<NamedType> findSubtypes(Class<S> clazz, Function<Class<JsonSubType>, JsonSubType> getter) { | |
private <S> List<NamedType> _findSubtypes(Class<S> clazz, Function<Class<JsonSubType>, JsonSubType> getter) { |
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@JacksonAnnotation | ||
public @interface JsonSubType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name sounds like it's part of @JsonSubTypes
of annotations
module. This may confuse users quite. If module name changes as per https://github.com/FasterXML/jackson-modules-base/pull/229/files#r1390329649, can we change name here also?
* more than one type name should be associated with the same type. | ||
* | ||
* @return subtype name array | ||
* @since 2.12 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Version mismatch, can remove.
* @since 2.12 |
... then add @since 2.16
to the class
* Therefore, we can {@link #unregisterType} a class and then module will reload this class's subclasses. | ||
*/ | ||
public class SubtypeModule extends Module { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Therefore, we can {@link #unregisterType} a class and then module will reload this class's subclasses. | |
*/ | |
public class SubtypeModule extends Module { | |
* Therefore, we can {@link #unregisterType} a class and then module will reload this class's subclasses. | |
* | |
* @since 2.16 | |
*/ | |
public class SubtypeModule extends Module { |
Quick note: due to timing, decided that I will not try to get this in Jackson 2.16 -- so will need to be re-based to 2.17. For example, I think that naming of But I need to read the PR in bit more thought to make sure my feedback is relevant. |
Adds a module that allows subtype to be registered without annotating the parent class.
It is implemented on SPI.
See FasterXML/jackson-databind#2104
Its original version is https://github.com/black-06/jackson-modules-dynamic-subtype.
I removed the custom ServiceLoader and always use the standard library,
which means that pojo always needs a no-parameter constructor.