Skip to content

Commit

Permalink
HREF's are now Optional<Link>'s and optional when parsing/rendering.
Browse files Browse the repository at this point in the history
Fixes #42.
  • Loading branch information
talios committed Jul 20, 2012
1 parent cc18ad0 commit cee2f92
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ public Representation newResource(URI uri) {
return newResource(uri.toASCIIString());
}

public Representation newResource() {
return newResource((String) null);
}

public Representation newResource(String href) {
MutableRepresentation resource = new MutableRepresentation(this, href);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ public Optional<T> render(ReadableRepresentation representation, Writer writer)

private void renderJson(JsonGenerator g, ReadableRepresentation representation, boolean embedded) throws IOException {

final Link resourceLink = representation.getResourceLink();
final String href = resourceLink.getHref();

if (!representation.getCanonicalLinks().isEmpty() || (!embedded && !representation.getNamespaces().isEmpty())) {
g.writeObjectFieldStart(LINKS);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,8 @@ protected BaseRepresentation(RepresentationFactory representationFactory) {
this.representationFactory = representationFactory;
}

public Link getResourceLink() {
try {
return Iterables.find(getLinks(), LinkPredicate.newLinkPredicate(Support.SELF));
} catch (NoSuchElementException e) {
throw new IllegalStateException("Resources MUST have a self link.");
}
public Optional<Link> getResourceLink() {
return Iterables.tryFind(getLinks(), LinkPredicate.newLinkPredicate(Support.SELF));
}

public Map<String, String> getNamespaces() {
Expand Down Expand Up @@ -263,7 +259,11 @@ public <T, V> Optional<V> ifSatisfiedBy(Class<T> anInterface, Function<T, V> fun
}

public String resolveRelativeHref(String href) {
return resolveRelativeHref(getResourceLink().getHref(), href);
if (getResourceLink().isPresent()) {
return resolveRelativeHref(getResourceLink().get().getHref(), href);
} else {
throw new IllegalStateException("Unable to resolve relative href with missing resource href.");
}
}

protected String resolveRelativeHref(final String baseHref, String href) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

public class ImmutableRepresentation extends BaseRepresentation {

private final Link resourceLink;
private final Optional<Link> resourceLink;

public ImmutableRepresentation(RepresentationFactory representationFactory,
Map<String, String> namespaces, List<Link> links, Map<String, Optional<Object>> properties, Multimap<String, Representation> resources, boolean hasNullProperties) {
Expand All @@ -26,7 +26,7 @@ public ImmutableRepresentation(RepresentationFactory representationFactory,
this.hasNullProperties = hasNullProperties;
}

public Link getResourceLink() {
public Optional<Link> getResourceLink() {
return resourceLink;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public class MutableRepresentation extends BaseRepresentation implements Represe

public MutableRepresentation(RepresentationFactory representationFactory, String href) {
super(representationFactory);
this.links.add(new Link(representationFactory, resolveRelativeHref(representationFactory.getBaseHref(), href), "self"));
if (href != null) {
this.links.add(new Link(representationFactory, resolveRelativeHref(representationFactory.getBaseHref(), href), "self"));
}
}

public MutableRepresentation(RepresentationFactory representationFactory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ public Optional<T> render(ReadableRepresentation representation, Writer writer)

private Element renderElement(String rel, ReadableRepresentation representation, boolean embedded) {

final Link resourceLink = representation.getResourceLink();
final String href = resourceLink.getHref();
final Optional<Link> resourceLink = representation.getResourceLink();

// Create the root element
final Element resourceElement = new Element("resource");
resourceElement.setAttribute("href", href);
if (resourceLink.isPresent()) {
resourceElement.setAttribute("href", resourceLink.get().getHref());
}

if (!rel.equals("self")) {
resourceElement.setAttribute("rel", rel);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public interface ReadableRepresentation {
* Returns a Link with a rel of "self".
* @return A Link
*/
Link getResourceLink();
Optional<Link> getResourceLink();

/**
* Returns an ImmutableMap of the currently defined resource namespaces
Expand Down
26 changes: 22 additions & 4 deletions src/test/java/com/theoryinpractise/halbuilder/RenderingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class RenderingTest {

private String exampleXml;
private String exampleJson;
private String exampleXmlWithoutHref;
private String exampleJsonWithoutHref;
private String exampleWithSubresourceXml;
private String exampleWithSubresourceJson;
private String exampleWithSubresourceLinkingToItselfXml;
Expand All @@ -45,6 +47,10 @@ public class RenderingTest {

@BeforeMethod
public void setup() throws IOException {
exampleXmlWithoutHref = Resources.toString(RenderingTest.class.getResource("exampleWithoutHref.xml"), Charsets.UTF_8)
.trim().replaceAll("\n", "\r\n");
exampleJsonWithoutHref = Resources.toString(RenderingTest.class.getResource("exampleWithoutHref.json"), Charsets.UTF_8)
.trim();
exampleXml = Resources.toString(RenderingTest.class.getResource("example.xml"), Charsets.UTF_8)
.trim().replaceAll("\n", "\r\n");
exampleJson = Resources.toString(RenderingTest.class.getResource("example.json"), Charsets.UTF_8)
Expand Down Expand Up @@ -132,12 +138,24 @@ public void testUriBuilderHal() {
.withProperty("optional", Boolean.TRUE)
.withProperty("expired", Boolean.FALSE);

assertThat(party.getResourceLink().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.getResourceLink().get().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.renderContent(RepresentationFactory.HAL_XML)).isEqualTo(exampleXml);
assertThat(party.renderContent(RepresentationFactory.HAL_JSON)).isEqualTo(exampleJson);

}

@Test
public void testResourcesWithoutHref() {

ReadableRepresentation party = new RepresentationFactory().newResource()
.withProperty("name", "Example Resource");

assertThat(party.getResourceLink().isPresent()).isFalse();
assertThat(party.renderContent(RepresentationFactory.HAL_XML)).isEqualTo(exampleXmlWithoutHref);
assertThat(party.renderContent(RepresentationFactory.HAL_JSON)).isEqualTo(exampleJsonWithoutHref);

}

@Test
public void testCustomerHal() {

Expand All @@ -149,7 +167,7 @@ public void testCustomerHal() {
.withProperty("optional", Boolean.TRUE)
.withProperty("expired", Boolean.FALSE);

assertThat(party.getResourceLink().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.getResourceLink().get().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.renderContent(RepresentationFactory.HAL_XML)).isEqualTo(exampleXml);
assertThat(party.renderContent(RepresentationFactory.HAL_JSON)).isEqualTo(exampleJson);

Expand Down Expand Up @@ -293,7 +311,7 @@ public void testNullPropertyHal() {
.withProperty("expired", Boolean.FALSE)
.withProperty("nullprop", null);

assertThat(party.getResourceLink().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.getResourceLink().get().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.renderContent(RepresentationFactory.HAL_XML)).isEqualTo(exampleWithNullPropertyXml);
assertThat(party.renderContent(RepresentationFactory.HAL_JSON)).isEqualTo(exampleWithNullPropertyJson);
}
Expand All @@ -311,7 +329,7 @@ public void testLiteralNullPropertyHal() {
.withProperty("expired", Boolean.FALSE)
.withProperty("nullval", "null");

assertThat(party.getResourceLink().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.getResourceLink().get().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(party.renderContent(RepresentationFactory.HAL_XML)).isEqualTo(exampleWithLiteralNullPropertyXml);
assertThat(party.renderContent(RepresentationFactory.HAL_JSON)).isEqualTo(exampleWithLiteralNullPropertyJson);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,17 @@ public Object[][] provideSubResources() {
};
}

@DataProvider
public Object[][] provideResourcesWithouHref() {
return new Object[][] {
{representationFactory.readResource(new InputStreamReader(ResourceReaderTest.class.getResourceAsStream("exampleWithoutHref.xml")))},
{representationFactory.readResource(new InputStreamReader(ResourceReaderTest.class.getResourceAsStream("exampleWithoutHref.json")))},
};
}

@Test(dataProvider = "provideResources")
public void testReader(ReadableRepresentation representation) {
assertThat(representation.getResourceLink().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(representation.getResourceLink().get().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(representation.getNamespaces()).hasSize(2);
assertThat(representation.getProperties().get("name").get()).isEqualTo("Example Resource");
assertThat(representation.get("name").get()).isEqualTo("Example Resource");
Expand Down Expand Up @@ -71,14 +79,22 @@ public void testLinkAttributes(ReadableRepresentation representation) {

@Test(dataProvider = "provideSubResources")
public void testSubReader(ReadableRepresentation representation) {
assertThat(representation.getResourceLink().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(representation.getResourceLink().get().getHref()).isEqualTo("https://example.com/api/customer/123456");
assertThat(representation.getNamespaces()).hasSize(2);
assertThat(representation.getCanonicalLinks()).hasSize(3);
assertThat(representation.getResources().values()).hasSize(1);
assertThat(representation.getResources().values().iterator().next().getProperties().get("name").get()).isEqualTo("Example User");
assertThat(representation.getResourcesByRel("ns:user")).hasSize(1);
}

@Test(dataProvider = "provideResourcesWithouHref")
public void testResourcesWithoutHref(ReadableRepresentation representation) {
assertThat(representation.getResourceLink().isPresent()).isFalse();
assertThat(representation.getNamespaces()).hasSize(0);
assertThat(representation.getCanonicalLinks()).hasSize(0);
assertThat(representation.get("name").get()).isEqualTo("Example Resource");
}

@Test(expectedExceptions = RepresentationException.class)
public void testUnknownFormat() {
representationFactory.readResource(new StringReader("!!!"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "Example Resource"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resource>
<name>Example Resource</name>
</resource>

0 comments on commit cee2f92

Please sign in to comment.