responseMap) {
+ this.responseMap = responseMap;
+ for (String url : responseMap.keySet()) {
+ resolved.put(url, 0);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * If the supplied {@code relationshipURL} is missing from the response Map, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
+ *
+ * @param relationshipURL URL. eg. users/1 or https://api.myhost.com/uers/1
+ * @return
+ * @throws IllegalArgumentException if {@code relationshipURL} is missing from the response Map.
+ */
+ @Override
+ public byte[] resolve(String relationshipURL) {
+ if (responseMap.containsKey(relationshipURL)) {
+ resolved.put(relationshipURL, resolved.get(relationshipURL)+1);
+ return responseMap.get(relationshipURL).getBytes();
+ }
+ throw new IllegalArgumentException("Unable to resolve + relationshipURL + , missing response map " +
+ "entry.");
+ }
+
+ /**
+ * Returns a map of relationship URLs and the number of times each URL was resolved.
+ *
+ * @return the resolution map
+ */
+ public Map getResolved() {
+ return resolved;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/github/jasminb/jsonapi/ResourceConverterTest.java b/src/test/java/com/github/jasminb/jsonapi/ResourceConverterTest.java
index 0d37d83..a9f217f 100644
--- a/src/test/java/com/github/jasminb/jsonapi/ResourceConverterTest.java
+++ b/src/test/java/com/github/jasminb/jsonapi/ResourceConverterTest.java
@@ -324,7 +324,10 @@ public void testLinkObjectsAndRelType() throws Exception {
Comment.class);
underTest.setGlobalResolver(resolver);
- List articles = underTest.readObjectCollection(apiResponse.getBytes(), Article.class);
+ JSONAPIDocument> responseDocument = underTest
+ .readDocumentCollection(apiResponse.getBytes(), Article.class);
+ Assert.assertNotNull(responseDocument);
+ List articles = responseDocument.get();
// Sanity check
Assert.assertNotNull(articles);
diff --git a/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Article.java b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Article.java
new file mode 100644
index 0000000..7d80be9
--- /dev/null
+++ b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Article.java
@@ -0,0 +1,56 @@
+package com.github.jasminb.jsonapi.resolutionstrategy;
+
+
+import com.github.jasminb.jsonapi.RelType;
+import com.github.jasminb.jsonapi.ResolutionStrategy;
+import com.github.jasminb.jsonapi.annotations.Id;
+import com.github.jasminb.jsonapi.annotations.Relationship;
+import com.github.jasminb.jsonapi.annotations.Type;
+
+import java.util.List;
+
+@Type("articles")
+public class Article {
+ @Id
+ private String id;
+
+ private String title;
+
+ @Relationship(value = "author", resolve = true, relType = RelType.RELATED, strategy = ResolutionStrategy.REF)
+ private String author;
+
+ @Relationship(value = "comments", resolve = true, relType = RelType.RELATED, strategy = ResolutionStrategy.OBJECT)
+ private List comments;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public List getComments() {
+ return comments;
+ }
+
+ public void setComments(List comments) {
+ this.comments = comments;
+ }
+}
diff --git a/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Author.java b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Author.java
new file mode 100644
index 0000000..5efefcc
--- /dev/null
+++ b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Author.java
@@ -0,0 +1,46 @@
+package com.github.jasminb.jsonapi.resolutionstrategy;
+
+
+import com.github.jasminb.jsonapi.annotations.Id;
+import com.github.jasminb.jsonapi.annotations.Type;
+
+@Type("people")
+public class Author {
+ @Id
+ private String id;
+ private String firstName;
+ private String lastName;
+ private String twitter;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getTwitter() {
+ return twitter;
+ }
+
+ public void setTwitter(String twitter) {
+ this.twitter = twitter;
+ }
+}
diff --git a/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Comment.java b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Comment.java
new file mode 100644
index 0000000..f657900
--- /dev/null
+++ b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Comment.java
@@ -0,0 +1,42 @@
+package com.github.jasminb.jsonapi.resolutionstrategy;
+
+
+import com.github.jasminb.jsonapi.RelType;
+import com.github.jasminb.jsonapi.ResolutionStrategy;
+import com.github.jasminb.jsonapi.annotations.Id;
+import com.github.jasminb.jsonapi.annotations.Relationship;
+import com.github.jasminb.jsonapi.annotations.Type;
+
+@Type("comments")
+public class Comment {
+ @Id
+ private String id;
+ private String body;
+
+ @Relationship(value = "author", resolve = true, relType = RelType.RELATED, strategy = ResolutionStrategy.REF)
+ private String author;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+}
diff --git a/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Foo.java b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Foo.java
new file mode 100644
index 0000000..2de7340
--- /dev/null
+++ b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/Foo.java
@@ -0,0 +1,46 @@
+package com.github.jasminb.jsonapi.resolutionstrategy;
+
+import com.github.jasminb.jsonapi.ResolutionStrategy;
+import com.github.jasminb.jsonapi.annotations.Id;
+import com.github.jasminb.jsonapi.annotations.Relationship;
+import com.github.jasminb.jsonapi.annotations.Type;
+
+/**
+ * Contains a @Relationship field that is resolved to a reference, but it assigned to a non-String field. Relationships
+ * that are resolved to a reference require a {@code String} type to store the reference.
+ */
+@Type("foo")
+public class Foo {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ @Relationship(value = "bar", resolve = true, strategy = ResolutionStrategy.REF)
+ private Integer bar;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getBar() {
+ return bar;
+ }
+
+ public void setBar(Integer bar) {
+ this.bar = bar;
+ }
+}
diff --git a/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/ResolutionStrategyTest.java b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/ResolutionStrategyTest.java
new file mode 100644
index 0000000..0a2479a
--- /dev/null
+++ b/src/test/java/com/github/jasminb/jsonapi/resolutionstrategy/ResolutionStrategyTest.java
@@ -0,0 +1,105 @@
+package com.github.jasminb.jsonapi.resolutionstrategy;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.github.jasminb.jsonapi.JSONAPIDocument;
+import com.github.jasminb.jsonapi.ProbeResolver;
+import com.github.jasminb.jsonapi.ResourceConverter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Insures that the @Relationship attribute {@code relationshipStrategy} is properly used to resolve relationship links
+ * to objects ({@code ResolutionStrategy#OBJECT}) or to String references ({@code ResolutionStrategy#REF)}.
+ */
+public class ResolutionStrategyTest {
+
+ private static final String COMMENTS_REL_LINK = "http://example.com/articles/1/comments";
+
+ private static final String COMMENT_1_ID = "5";
+
+ private static final String COMMENT_1_BODY = "First!";
+
+ private static final String COMMENT_1_AUTHOR_REL_LINK = "http://example.com/comments/5/author";
+
+ private static final String COMMENT_2_ID = "12";
+
+ private static final String COMMENT_2_BODY = "I like XML better";
+
+ private static final String COMMENT_2_AUTHOR_REL_LINK = "http://example.com/comments/12/author";
+
+ private static final String ARTICLES_AUTHOR_REL_LINK = "http://example.com/articles/1/author";
+
+
+ /**
+ * Insures that {@link com.github.jasminb.jsonapi.ResolutionStrategy} is properly used to resolve objects or string
+ * references. In this test, the {@code Article} uses an object resolution strategy when resolving {@code Comment}
+ * objects, and records {@code String} references (i.e. uses a reference resolution strategy) when resolving
+ * {@code Author} objects.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testResolutionStrategy() throws Exception {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE);
+
+ Map responseMap = new HashMap<>();
+ responseMap.put(ARTICLES_AUTHOR_REL_LINK, "");
+ responseMap.put(COMMENTS_REL_LINK, org.apache.commons.io.IOUtils.toString(
+ this.getClass().getResource("comments-response.json"), "UTF-8"));
+ ProbeResolver resolver = new ProbeResolver(responseMap);
+
+ ResourceConverter underTest = new ResourceConverter(mapper, Article.class, Comment.class);
+ underTest.setGlobalResolver(resolver);
+
+ JSONAPIDocument> responseDocument = underTest.readDocumentCollection(
+ org.apache.commons.io.IOUtils.toString(
+ this.getClass().getResource("articles.json"), "UTF-8")
+ .getBytes(),
+ Article.class);
+ Assert.assertNotNull(responseDocument);
+ List articles = responseDocument.get();
+
+ // Sanity checks
+ Assert.assertNotNull(articles);
+ Assert.assertEquals(1, articles.size());
+ List comments = articles.get(0).getComments();
+ Assert.assertEquals(1, resolver.getResolved().get(COMMENTS_REL_LINK).intValue());
+ Assert.assertEquals(0, resolver.getResolved().get(ARTICLES_AUTHOR_REL_LINK).intValue());
+
+ // Comments resolution strategy used objects
+ Assert.assertNotNull(comments);
+ Assert.assertEquals(2, comments.size());
+ Assert.assertEquals(COMMENT_1_ID, comments.get(0).getId());
+ Assert.assertEquals(COMMENT_1_BODY, comments.get(0).getBody());
+ Assert.assertEquals(COMMENT_2_ID, comments.get(1).getId());
+ Assert.assertEquals(COMMENT_2_BODY, comments.get(1).getBody());
+
+ // Author resolution strategy used references
+ Assert.assertEquals(ARTICLES_AUTHOR_REL_LINK, articles.get(0).getAuthor());
+ Assert.assertEquals(COMMENT_1_AUTHOR_REL_LINK, comments.get(0).getAuthor());
+ Assert.assertEquals(COMMENT_2_AUTHOR_REL_LINK, comments.get(1).getAuthor());
+ }
+
+ /**
+ * The {@code ResolutionStrategy#REF reference resolution strategy} requires that the field be a String.
+ *
+ * @throws Exception
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testNonStringRefField() throws Exception {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE);
+ ResourceConverter underTest = new ResourceConverter(mapper, Foo.class);
+ underTest.setGlobalResolver(new ProbeResolver(Collections.emptyMap()));
+
+ underTest.readDocument(org.apache.commons.io.IOUtils.toString(
+ this.getClass().getResource("foo.json"), "UTF-8").getBytes(), Foo.class);
+ }
+}
diff --git a/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/articles.json b/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/articles.json
new file mode 100644
index 0000000..2514894
--- /dev/null
+++ b/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/articles.json
@@ -0,0 +1,31 @@
+{
+ "data": [{
+ "type": "articles",
+ "id": "1",
+ "attributes": {
+ "title": "JSON API paints my bikeshed!"
+ },
+ "links": {
+ "self": "http://example.com/articles/1"
+ },
+ "relationships": {
+ "author": {
+ "links": {
+ "related": "http://example.com/articles/1/author"
+ }
+ },
+ "comments": {
+ "links": {
+ "related": "http://example.com/articles/1/comments"
+ },
+ "data": [{
+ "type": "comments",
+ "id": "5"
+ }, {
+ "type": "comments",
+ "id": "12"
+ }]
+ }
+ }
+ }]
+}
\ No newline at end of file
diff --git a/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/comments-response.json b/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/comments-response.json
new file mode 100644
index 0000000..8429c7a
--- /dev/null
+++ b/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/comments-response.json
@@ -0,0 +1,38 @@
+{
+ "data": [
+ {
+ "type": "comments",
+ "id": "5",
+ "attributes": {
+ "body": "First!"
+ },
+ "relationships": {
+ "author": {
+ "links": {
+ "related": "http://example.com/comments/5/author"
+ }
+ }
+ },
+ "links": {
+ "self": "http://example.com/comments/5"
+ }
+ },
+ {
+ "type": "comments",
+ "id": "12",
+ "attributes": {
+ "body": "I like XML better"
+ },
+ "relationships": {
+ "author": {
+ "links": {
+ "related": "http://example.com/comments/12/author"
+ }
+ }
+ },
+ "links": {
+ "self": "http://example.com/comments/12"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/foo.json b/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/foo.json
new file mode 100644
index 0000000..69024b6
--- /dev/null
+++ b/src/test/resources/com/github/jasminb/jsonapi/resolutionstrategy/foo.json
@@ -0,0 +1,16 @@
+{
+ "data": {
+ "type": "foo",
+ "id": "1",
+ "attributes": {
+ "name": "foo"
+ },
+ "relationships": {
+ "bar": {
+ "links": {
+ "self": "http://example.com/foo/rels/bar"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file