Skip to content

Commit

Permalink
Merge branch 'release/1.0.3'
Browse files Browse the repository at this point in the history
* release/1.0.3:
  [maven-release-plugin] prepare for next development iteration
  [maven-release-plugin] prepare release halbuilder-1.0.3
  Fixed up my local tests following Joost's merge.
  Fix ResourceReader.read implementation signatures
  Revert import rearrangement
  Added simple UriBuilder based test.
  Replace tabs with spaces
  Change references to ReadableResource
  Remove RenderableResource
  Add URI convenience Resource.withLink methods
  Fold RenderableResource into ReadableResource
  Renamed newResource(Reader) to readResource(Reader)
  Add URI convenience methods to ResourceFactory
  Make constants final
  Fix small typo in example.
  • Loading branch information
talios committed Apr 19, 2012
2 parents dab54ec + e74041f commit 99eaad0
Show file tree
Hide file tree
Showing 19 changed files with 195 additions and 122 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -19,8 +19,8 @@ Halbuilder is a simple Java API for generating and consuming HAL documents confo
.withProperty("summary", "An example list")
.withSubresource("td:owner", owner);

String xml = halResource.renderContent(ResourceFactory.HALXML);
String json = halResource.renderContent(ResourceFactory.HALJSON);
String xml = halResource.asRenderableResource().renderContent(ResourceFactory.HAL_XML);
String json = halResource.asRenderableResource().renderContent(ResourceFactory.HAL_JSON);

### Reading Local Resources

Expand Down
8 changes: 7 additions & 1 deletion pom.xml
Expand Up @@ -3,7 +3,7 @@

<groupId>com.theoryinpractise</groupId>
<artifactId>halbuilder</artifactId>
<version>1.0.3-SNAPSHOT</version>
<version>1.0.4-SNAPSHOT</version>
<description>Java based builder for the Hal specification http://stateless.co/hal_specification.html</description>
<packaging>jar</packaging>

Expand Down Expand Up @@ -129,6 +129,12 @@
<version>6.2.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.13-b01</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion src/it/clojure-hal/pom.xml
Expand Up @@ -29,7 +29,7 @@
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.theoryinpractise</groupId>
Expand Down
2 changes: 1 addition & 1 deletion src/it/clojure-hal/src/test/clojure/haltest.clj
Expand Up @@ -6,4 +6,4 @@
resource (doto (.newResource resource-factory "/foo")
(.withProperty "name" "Mark")
(.withLink "/home" "home"))]
(println (.renderContent (.asRenderableResource resource) "application/hal+xml"))) )
(println (.renderContent resource "application/hal+xml"))) )
15 changes: 12 additions & 3 deletions src/main/java/com/theoryinpractise/halbuilder/ResourceFactory.java
Expand Up @@ -19,6 +19,7 @@

import java.io.BufferedReader;
import java.io.Reader;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
Expand All @@ -27,8 +28,8 @@

public class ResourceFactory {

public static String HAL_XML = "application/hal+xml";
public static String HAL_JSON = "application/hal+json";
public static final String HAL_XML = "application/hal+xml";
public static final String HAL_JSON = "application/hal+json";

private Map<ContentType, Class<? extends Renderer>> contentRenderers = Maps.newHashMap();
private TreeMap<String, String> namespaces = Maps.newTreeMap(Ordering.usingToString());
Expand All @@ -39,6 +40,10 @@ public ResourceFactory() {
this("http://localhost");
}

public ResourceFactory(URI baseUri) {
this(baseUri.toASCIIString());
}

public ResourceFactory(String baseHref) {
this.baseHref = baseHref;
this.contentRenderers.put(new ContentType(HAL_XML), XmlRenderer.class);
Expand Down Expand Up @@ -67,6 +72,10 @@ public ResourceFactory withLink(String url, String rel) {
return this;
}

public Resource newResource(URI uri) {
return newResource(uri.toASCIIString());
}

public Resource newResource(String href) {
MutableResource resource = new MutableResource(this, href);

Expand All @@ -84,7 +93,7 @@ public Resource newResource(String href) {
return resource;
}

public ReadableResource newResource(Reader reader) {
public ReadableResource readResource(Reader reader) {
try {
Reader bufferedReader = new BufferedReader(reader);
bufferedReader.mark(1);
Expand Down
@@ -1,10 +1,9 @@
package com.theoryinpractise.halbuilder.impl.api;

import com.theoryinpractise.halbuilder.spi.ReadableResource;
import com.theoryinpractise.halbuilder.spi.RenderableResource;

import java.io.Reader;

public interface ResourceReader {
RenderableResource read(Reader source);
ReadableResource read(Reader source);
}
Expand Up @@ -6,7 +6,6 @@
import com.theoryinpractise.halbuilder.impl.api.ResourceReader;
import com.theoryinpractise.halbuilder.impl.resources.MutableResource;
import com.theoryinpractise.halbuilder.spi.ReadableResource;
import com.theoryinpractise.halbuilder.spi.RenderableResource;
import com.theoryinpractise.halbuilder.spi.ResourceException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
Expand All @@ -23,23 +22,22 @@
import static com.theoryinpractise.halbuilder.impl.api.Support.TITLE;
import static com.theoryinpractise.halbuilder.impl.api.Support.NAME;


public class JsonResourceReader implements ResourceReader {
private ResourceFactory resourceFactory;

public JsonResourceReader(ResourceFactory resourceFactory) {
this.resourceFactory = resourceFactory;
}

public RenderableResource read(Reader reader) {
public ReadableResource read(Reader reader) {
try {
ObjectMapper mapper = new ObjectMapper();

JsonNode rootNode = mapper.readValue(reader, JsonNode.class);

MutableResource resource = readResource(rootNode);

return resource.asRenderableResource();
return resource.toImmutableResource();
} catch (Exception e) {
throw new ResourceException(e);
}
Expand Down
Expand Up @@ -5,7 +5,6 @@
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand All @@ -21,7 +20,6 @@
import com.theoryinpractise.halbuilder.spi.Contract;
import com.theoryinpractise.halbuilder.spi.Link;
import com.theoryinpractise.halbuilder.spi.ReadableResource;
import com.theoryinpractise.halbuilder.spi.RenderableResource;
import com.theoryinpractise.halbuilder.spi.Resource;
import com.theoryinpractise.halbuilder.spi.ResourceException;

Expand All @@ -44,7 +42,6 @@
import static com.theoryinpractise.halbuilder.impl.resources.LinkPredicate.newLinkPredicate;
import static java.lang.String.format;


public abstract class BaseResource implements ReadableResource {

public static final Ordering<Link> RELATABLE_ORDERING = Ordering.from(new Comparator<Link>() {
Expand Down Expand Up @@ -252,7 +249,7 @@ protected String resolveRelativeHref(final String baseHref, String href) {

}

public RenderableResource asRenderableResource() {
public ImmutableResource toImmutableResource() {
return new ImmutableResource(resourceFactory, getNamespaces(), getCanonicalLinks(), getProperties(), getResources());
}

Expand Down
Expand Up @@ -5,15 +5,14 @@
import com.theoryinpractise.halbuilder.impl.bytecode.InterfaceContract;
import com.theoryinpractise.halbuilder.impl.bytecode.InterfaceRenderer;
import com.theoryinpractise.halbuilder.spi.Link;
import com.theoryinpractise.halbuilder.spi.RenderableResource;
import com.theoryinpractise.halbuilder.spi.Renderer;
import com.theoryinpractise.halbuilder.spi.Resource;

import java.io.StringWriter;
import java.util.List;
import java.util.Map;

public class ImmutableResource extends BaseResource implements RenderableResource {
public class ImmutableResource extends BaseResource {

private final Link resourceLink;

Expand Down
Expand Up @@ -4,8 +4,11 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.theoryinpractise.halbuilder.ResourceFactory;
import com.theoryinpractise.halbuilder.impl.bytecode.InterfaceContract;
import com.theoryinpractise.halbuilder.impl.bytecode.InterfaceRenderer;
import com.theoryinpractise.halbuilder.spi.Link;
import com.theoryinpractise.halbuilder.spi.ReadableResource;
import com.theoryinpractise.halbuilder.spi.Renderer;
import com.theoryinpractise.halbuilder.spi.Resource;
import com.theoryinpractise.halbuilder.spi.ResourceException;
import com.theoryinpractise.halbuilder.spi.Serializable;
Expand All @@ -14,9 +17,11 @@
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.net.URI;

import static com.theoryinpractise.halbuilder.impl.api.Support.WHITESPACE_SPLITTER;
import static java.lang.String.format;
Expand Down Expand Up @@ -47,6 +52,17 @@ public MutableResource withLink(String href, String rel) {
return this;
}

/**
* Add a link to this resource
* @param uri The target URI for the link, possibly relative to the href of
* this resource.
* @param rel
* @return
*/
public MutableResource withLink(URI uri, String rel) {
return withLink(uri.toASCIIString(), rel);
}

/**
* Add a link to this resource
* @param href The target href for the link, relative to the href of this resource.
Expand All @@ -64,11 +80,22 @@ public MutableResource withLink(String href, String rel, Predicate<ReadableResou

/**
* Add a link to this resource
* @param href The target href for the link, relative to the href of this resource.
* @param uri The target URI for the link, possibly relative to the href of
* this resource.
* @param rel
* @return
*/
public MutableResource withLink(String href, String rel, Optional<Predicate<ReadableResource>> predicate, Optional<String> name, Optional<String> title, Optional<String> hreflang) {
public MutableResource withLink(URI uri, String rel, Predicate<ReadableResource> predicate) {
return withLink(uri.toASCIIString(), rel, predicate);
}

/**
* Add a link to this resource
* @param href The target href for the link, relative to the href of this resource.
* @param rel
* @return
*/
public MutableResource withLink(String href, String rel, Optional<Predicate<ReadableResource>> predicate, Optional<String> name, Optional<String> title, Optional<String> hreflang) {
if (predicate.or(Predicates.<ReadableResource>alwaysTrue()).apply(this)) {
String resolvedHref = resolvableUri.matcher(href).matches() ? resolveRelativeHref(href) : href;
for (String reltype : WHITESPACE_SPLITTER.split(rel)) {
Expand All @@ -80,6 +107,17 @@ public MutableResource withLink(String href, String rel, Optional<Predicate<Read
return this;
}

/**
* Add a link to this resource
* @param uri The target URI for the link, possibly relative to the href of
* this resource.
* @param rel
* @return
*/
public MutableResource withLink(URI uri, String rel, Optional<Predicate<ReadableResource>> predicate, Optional<String> name, Optional<String> title, Optional<String> hreflang) {
return withLink(uri.toASCIIString(), rel, predicate, name, title, hreflang);
}

public Resource withProperty(String name, Object value) {
if (properties.containsKey(name)) {
throw new ResourceException(format("Duplicate property '%s' found for resource", name));
Expand Down Expand Up @@ -156,4 +194,29 @@ public MutableResource withSubresource(String rel, Resource resource) {
return this;
}

/**
* Renders the current Resource as a proxy to the provider interface
*
* @param anInterface The interface we wish to proxy the resource as
* @return A Guava Optional of the rendered class, this will be absent if the interface doesn't satisfy the interface
*/
public <T> Optional<T> renderClass(Class<T> anInterface) {
if (InterfaceContract.newInterfaceContract(anInterface).isSatisfiedBy(this)) {
return InterfaceRenderer.newInterfaceRenderer(anInterface).render(toImmutableResource(), null);
} else {
return Optional.absent();
}
}

public String renderContent(String contentType) {
Renderer<String> renderer = resourceFactory.lookupRenderer(contentType);
return renderAsString(renderer);
}

private String renderAsString(final Renderer renderer) {
validateNamespaces(this);
StringWriter sw = new StringWriter();
renderer.render(toImmutableResource(), sw);
return sw.toString();
}
}
Expand Up @@ -6,10 +6,8 @@
import com.theoryinpractise.halbuilder.impl.api.ResourceReader;
import com.theoryinpractise.halbuilder.impl.resources.MutableResource;
import com.theoryinpractise.halbuilder.spi.ReadableResource;
import com.theoryinpractise.halbuilder.spi.RenderableResource;
import com.theoryinpractise.halbuilder.spi.Resource;
import com.theoryinpractise.halbuilder.spi.ResourceException;
import org.codehaus.jackson.JsonNode;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
Expand All @@ -31,19 +29,19 @@ public XmlResourceReader(ResourceFactory resourceFactory) {
this.resourceFactory = resourceFactory;
}

public RenderableResource read(Reader reader) {
public ReadableResource read(Reader reader) {
try {
Document d = new SAXBuilder().build(reader);
Element root = d.getRootElement();
return readResource(root).asRenderableResource();
return readResource(root).toImmutableResource();
} catch (JDOMException e) {
throw new ResourceException(e);
} catch (IOException e) {
throw new ResourceException(e);
}
}

private Resource readResource(Element root) {
private MutableResource readResource(Element root) {
String href = root.getAttributeValue("href");
MutableResource resource = new MutableResource(resourceFactory, href);

Expand Down
Expand Up @@ -96,9 +96,21 @@ public interface ReadableResource {
<T, V> Optional<V> ifSatisfiedBy(Class<T> anInterface, Function<T, V> function);

/**
* Return the resource as a optimized for rendering resource.
* @return A RenderableResource
* Returns an optional proxy to the given interface mirroring the resource.
*
* @param anInterface An interface to mirror
* @return A Guava Optional Resource Proxy
*/
RenderableResource asRenderableResource();
<T> Optional<T> renderClass(Class<T> anInterface);

/**
* Returns the resource in the request content-type.
*
* application/hal+xml and application/hal+json are provided by default,
* additional Renderers can be added to a ResourceFactory.
*
* @param contentType The content type requested
* @return A String
*/
String renderContent(String contentType);
}

This file was deleted.

0 comments on commit 99eaad0

Please sign in to comment.