Skip to content
This repository was archived by the owner on Nov 13, 2019. It is now read-only.

Commit a5ca53a

Browse files
committed
Fixes two bugs related to relationship processing:
- Insures that different relationships that share the same URL result in the resolution of the same object for each relationship - Insures that encountering the same relationship twice does not prevent the processing of remaining relationships.
1 parent ca06c52 commit a5ca53a

2 files changed

Lines changed: 43 additions & 7 deletions

File tree

src/main/java/com/github/jasminb/jsonapi/ResolverState.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.github.jasminb.jsonapi;
22

33
import java.lang.reflect.Field;
4+
import java.util.HashMap;
45
import java.util.HashSet;
6+
import java.util.Map;
57
import java.util.Set;
68

79
/**
@@ -25,6 +27,11 @@ class ResolverState {
2527
*/
2628
private final Set<String> visited = new HashSet<>();
2729

30+
/**
31+
* Maintains a cache of objects that have been deserialized
32+
*/
33+
private final Map<String, Object> cache = new HashMap<>();
34+
2835
/**
2936
* Constructs a new state object.
3037
*
@@ -57,6 +64,20 @@ boolean visited(String url) {
5764
return !this.visited.add(url);
5865
}
5966

67+
Object cache(String url, Object object) {
68+
cache.put(url, object);
69+
return object;
70+
}
71+
72+
boolean isCached(String url) {
73+
return cache.containsKey(url);
74+
}
75+
76+
Object retrieve(String url) {
77+
return cache.get(url);
78+
}
79+
80+
6081
/**
6182
* Used by the relationship resolution implementation to maintain the relationship type being resolved for this
6283
* {@code {@link #getField() field}. Typically "related" or "self".

src/main/java/com/github/jasminb/jsonapi/ResourceConverter.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -466,23 +466,35 @@ private void handleRelationships(JsonNode source, Object object, Map<String, Obj
466466
}
467467

468468
if (resolverState.visited(link)) {
469-
return;
469+
if (resolverState.isCached(link)) {
470+
relationshipField.set(object, resolverState.retrieve(link));
471+
}
472+
continue;
470473
}
471474

472475
byte[] content = resolver.resolve(link);
473476

474477
if (hasResourceLinkage(relationship)) {
478+
Object resolvedObject = null;
475479
if (isCollection(relationship)) {
476-
relationshipField.set(object, readObjectCollectionInternal(content, type, resolverState));
477-
} else if (hasResourceLinkage(relationship)) {
478-
relationshipField.set(object, readObjectInternal(content, type, resolverState));
479-
}
480+
resolvedObject = readObjectCollectionInternal(content, type, resolverState);
481+
relationshipField.set(object, resolvedObject);
482+
} else if (hasResourceLinkage(relationship)) {
483+
resolvedObject = readObjectInternal(content, type, resolverState);
484+
relationshipField.set(object, resolvedObject);
485+
}
486+
if (resolvedObject != null) {
487+
resolverState.cache(link, resolvedObject);
488+
}
480489
} else {
481490
JsonNode resolvedNode = objectMapper.readTree(content);
491+
Object resolvedObject = null;
482492
if (ValidationUtils.isCollection(resolvedNode)) {
483-
relationshipField.set(object, readObjectCollectionInternal(content, type, resolverState));
493+
resolvedObject = readObjectCollectionInternal(content, type, resolverState);
494+
relationshipField.set(object, resolvedObject);
484495
} else if (ValidationUtils.isObject(resolvedNode)) {
485-
relationshipField.set(object, readObjectInternal(content, type, resolverState));
496+
resolvedObject = readObjectInternal(content, type, resolverState);
497+
relationshipField.set(object, resolvedObject);
486498
} else if (ErrorUtils.hasErrors(resolvedNode)){
487499
ErrorResponse errors = ErrorUtils.parseError(resolvedNode);
488500
StringBuilder msg = new StringBuilder("Unable to parse the response document for " +
@@ -504,6 +516,9 @@ private void handleRelationships(JsonNode source, Object object, Map<String, Obj
504516
throw new RuntimeException("Response document for '" + link + "' does not contain" +
505517
" primary data.");
506518
}
519+
if (resolvedObject != null) {
520+
resolverState.cache(link, resolvedObject);
521+
}
507522
}
508523
}
509524
} else {

0 commit comments

Comments
 (0)