[master] Json refactoring (step 1/2 - isolating Jackson from our code)#1145
[master] Json refactoring (step 1/2 - isolating Jackson from our code)#1145mathieucarbou merged 1 commit intoTerracotta-OSS:masterfrom mathieucarbou:json
Conversation
|
(rebased) |
@mathieucarbou When moving to some other json library then mixin present in *.json package in all the affected modules will still need to be changed right ? |
Yes! This PR is just isolating all the TC code from Jackson. Currently in platform all the Jackson imports are everywhere. TC code is tightly coupled with Jackson. This PR (1/2) is a first step: it isolates jackson imports in:
Then, when converting to Gson, only rewriting those impl will be required because all the TC code now depends on the new TC Json API I introduced here. Next PR (2/2) will switch the Json Factory impl and these mpdules to Gson. |
| public String toString() { | ||
| return "ObjectMapperFactory{" + | ||
| "pretty=" + pretty + | ||
| ", modules=" + modules + |
| } | ||
| for (Json.Module module : modules) { | ||
| if (module instanceof JacksonModule) { | ||
| ((JacksonModule) module).configure(mapper); |
There was a problem hiding this comment.
style: can you move this in the for-loop above.
There was a problem hiding this comment.
no... modules need to be registered before triggering the configuration because there are some dependencies to resolve ;-) I will add a comment.
| } | ||
|
|
||
| @Override | ||
| public void removeKey(String key) { |
There was a problem hiding this comment.
I think this would be better named as clearValue.
There was a problem hiding this comment.
Ahah! That's the catch ;-) It is really a remove. The main object is SanskritObjectImpl. This map is just a visitor collecting the different sanskrit operations. And the removal operation, so that is gets serialized correctly in json, needs to have a representation in the map so that it can be serialized. In sanskrit, a removal is mapped to a key associated to null.
this si completely different with the sanskritobjectimpl which holds the object graph and is mutated by sanskrit operations.
| setLong(key, (Long) value); | ||
| } else if (value instanceof SanskritObject) { | ||
| setObject(key, (SanskritObject) value); | ||
| } else if (value == null || value instanceof Number) { |
There was a problem hiding this comment.
Cannot this block just be removed and handled by the final one.
| private final T body; | ||
|
|
||
| @JsonCreator | ||
| public DiagnosticResponseMixin(@JsonProperty("body") T body, |
There was a problem hiding this comment.
Is it OK to have an empty body? That is, should it be required?
There was a problem hiding this comment.
Yes, totally. Jackson mixing are just a way to apply Jackson annotations to model classes without touching them.
Model classes will remain as-is. But All this Jackson modules containing mixing and serializers will be converted to Gson mappers at the end.
Here, what is important are the annotations, that are applied to the real object thanks to the mixin declaration above.
| } | ||
|
|
||
| @Override | ||
| public <T> T map(SanskritObject src, Class<T> dest, String version) throws SanskritException { |
There was a problem hiding this comment.
No it is used ;-) In the real impl in the persistence module.
| .replaceAll("\"buildId\":\"[^\"]*\"", "\"buildId\":\"Build ID\"") | ||
| .replaceAll("\"version\":\"[^\"]*\"", "\"version\":\"<version>\"") | ||
| .replaceAll("\"clientId\":\"[0-9]+@[^:]*:([^:]*):[^\"]*\"", "\"clientId\":\"[email protected]:$1:<uuid>\"") | ||
| .replaceAll("\"clientId\":\"[0-9]+@[^:]*:([^:]*):[^\"]*\"", "\"clientId\": \"[email protected]:$1:<uuid>\"") |
There was a problem hiding this comment.
I don't see any other spaces-after-semi colons in here. Was this purposeful?
There was a problem hiding this comment.
weird! I don't know how it happened...
| try { | ||
| return mapper.readTree(new File(AbstractTest.class.getResource("/" + file).toURI())); | ||
| } catch (Exception e) { | ||
| return mapper.parse(new File(AbstractTest.class.getResource("/" + file).toURI())); |
There was a problem hiding this comment.
I guess I wonder why not use the parse(URL) version?
There was a problem hiding this comment.
I just replaced the method calls ;-) not did a full replace ;-)
| } | ||
|
|
||
| @Override | ||
| public <T> T map(SanskritObject src, Class<T> dest, String version) throws SanskritException { |
There was a problem hiding this comment.
no, it is really used ;-)
| /** | ||
| * @author Mathieu Carbou | ||
| */ | ||
| public class TestModule extends SimpleModule implements Json.Module { |
There was a problem hiding this comment.
Is it possible to consolidate the various TestModules and TestData?
There was a problem hiding this comment.
No: TestData are the pojo classes used for testing.
TestModule are the mixin annotations telling the json framework how to serialise and deserialise the objects... So first one is completely json unrelated (normal java classes) and the json module is currently implemented with jackson, but soon wil be implemented with gson.
The TestData classes won't be touched for the Jackson => Gson switch
(there is also no common place for these testing classes)
|
(rebased) |
* Isolate Jackson classes from Terracotta code * Introduced Terracotta Json API (currently implemented by Jackson) * Refactored Sanskrit to get rid of its coupling with Jackson classes
This refactoring is a first step required to switch to Gson, but also anyway a good refactoring to have in order to isolate Jackson from our code and reduce the direct dependencies we have on it.
*.jsonpackage