Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>

</dependencies>

<distributionManagement>
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/github/jasminb/jsonapi/ResolutionStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.github.jasminb.jsonapi;

/**
* Represents different strategies for resolving relationships.
*/
public enum ResolutionStrategy {

/**
* Strategy which resolves the relationship URL (as specified by the {@code relType} attribute on the
* {@code Relationship}) using a {@link RelationshipResolver}, and subsequently deserializes the JSON response into
* a Java object.
*/
OBJECT,

/**
* Strategy which simply stores the relationship URL (as specified by the {@code relType} attribute on the
* {@code Relationship}) in String field on an object.
*/
REF

}
12 changes: 12 additions & 0 deletions src/main/java/com/github/jasminb/jsonapi/ResourceConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,18 @@ private void handleRelationships(JsonNode source, Object object)
String link;

if (linkNode != null && ((link = getLink(linkNode)) != null)) {
if (configuration.getFieldRelationship(relationshipField).strategy() == ResolutionStrategy.REF) {
if (String.class.isAssignableFrom(relationshipField.getType())) {
relationshipField.set(object, link);
continue;
}

throw new IllegalArgumentException("Reference resolution strategy requires String " +
"type, but " + relationshipField.getDeclaringClass().getName() + "#" +
relationshipField.getName() + " has type " +
relationshipField.getType().getName());
}

if (isCollection(relationship)) {
relationshipField.set(object,
readDocumentCollection(resolver.resolve(link), type).get());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.jasminb.jsonapi.annotations;

import com.github.jasminb.jsonapi.RelType;
import com.github.jasminb.jsonapi.ResolutionStrategy;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand All @@ -20,4 +21,5 @@
boolean resolve() default false;
boolean serialise() default true;
RelType relType() default RelType.SELF;
ResolutionStrategy strategy() default ResolutionStrategy.OBJECT;
}
63 changes: 63 additions & 0 deletions src/test/java/com/github/jasminb/jsonapi/ProbeResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.github.jasminb.jsonapi;

import java.util.HashMap;
import java.util.Map;

/**
* Simple global RelationshipResolver implementation that maintains a count of responses for each resolution of a
* relationship url.
*/
public class ProbeResolver implements RelationshipResolver {

/**
* Map of relationship urls to the response JSON
*/
private Map<String, String> responseMap;

/**
* Map of relationship to a count of the times they have been resolved
*/
private Map<String, Integer> resolved = new HashMap<>();

/**
* Construct a new instance, supplying a Map of relationship URLs to a String of serialized JSON.
*
* @param responseMap response JSON keyed by relationship url
*/
public ProbeResolver(Map<String, String> responseMap) {
this.responseMap = responseMap;
for (String url : responseMap.keySet()) {
resolved.put(url, 0);
}
}

/**
* {@inheritDoc}
* <p>
* If the supplied {@code relationshipURL} is missing from the response Map, then an
* {@code IllegalArgumentException} is thrown.
* </p>
*
* @param relationshipURL URL. eg. <code>users/1</code> or <code>https://api.myhost.com/uers/1</code>
* @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<String, Integer> getResolved() {
return resolved;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ public void testLinkObjectsAndRelType() throws Exception {
Comment.class);
underTest.setGlobalResolver(resolver);

List<Article> articles = underTest.readObjectCollection(apiResponse.getBytes(), Article.class);
JSONAPIDocument<List<Article>> responseDocument = underTest
.readDocumentCollection(apiResponse.getBytes(), Article.class);
Assert.assertNotNull(responseDocument);
List<Article> articles = responseDocument.get();

// Sanity check
Assert.assertNotNull(articles);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Comment> 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<Comment> getComments() {
return comments;
}

public void setComments(List<Comment> comments) {
this.comments = comments;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading