Incorporate feedback from @rstoyanchev.

Improve ResourceAssemblerSupport by introducing a dedicated method instead of an overload. Got rid of EntityId in the course. ControllerLinkBuilder now inspects type hierarchy for @RequestMapping annotations instead of the class only. Made links list in ResourceSupport final. Polished variable names and JavaDoc.
This commit is contained in:
Oliver Gierke
2012-07-19 13:32:02 +02:00
parent 8b9c638869
commit cd3e433d98
5 changed files with 32 additions and 48 deletions

View File

@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
public class ResourceSupport implements Identifiable<Link> {
@XmlElement(name = "link", namespace = Link.ATOM_NAMESPACE)
private List<Link> links;
private final List<Link> links;
public ResourceSupport() {
this.links = new ArrayList<Link>();

View File

@@ -35,16 +35,16 @@ import org.springframework.web.util.UriTemplate;
*/
public class ControllerLinkBuilder {
private final UriComponents builder;
private final UriComponents uriComponents;
/**
* Creates a new {@link ControllerLinkBuilder}.
*
* @param builder must not be {@literal null}.
* @param uriComponents must not be {@literal null}.
*/
private ControllerLinkBuilder(UriComponentsBuilder builder) {
Assert.notNull(builder);
this.builder = builder.build();
this.uriComponents = builder.build();
}
/**
@@ -59,7 +59,7 @@ public class ControllerLinkBuilder {
public static ControllerLinkBuilder linkTo(Class<?> controller, Object... parameters) {
RequestMapping annotation = controller.getAnnotation(RequestMapping.class);
RequestMapping annotation = AnnotationUtils.findAnnotation(controller, RequestMapping.class);
String[] mapping = annotation == null ? new String[0] : (String[]) AnnotationUtils.getValue(annotation);
if (mapping.length > 1) {
@@ -89,12 +89,12 @@ public class ControllerLinkBuilder {
}
String[] segments = StringUtils.tokenizeToStringArray(object.toString(), "/");
return new ControllerLinkBuilder(UriComponentsBuilder.fromUri(builder.toUri()).pathSegment(segments));
return new ControllerLinkBuilder(UriComponentsBuilder.fromUri(uriComponents.toUri()).pathSegment(segments));
}
/**
* Adds the given {@link AbstractEntity}'s id as sub-resource. Will simply return the current builder if the given
* entity is {@literal null}.
* Adds the given {@link AbstractEntity}'s id as sub-resource. Will simply return the current uriComponents if the
* given entity is {@literal null}.
*
* @param identifyable
* @return
@@ -109,12 +109,12 @@ public class ControllerLinkBuilder {
}
/**
* Returns a URI resulting from the builder.
* Returns a URI resulting from the uriComponents.
*
* @return
*/
public URI toUri() {
return builder.encode().toUri();
return uriComponents.encode().toUri();
}
public Link withRel(String rel) {

View File

@@ -36,25 +36,6 @@ import org.springframework.util.Assert;
public abstract class ResourceAssemblerSupport<T extends Identifiable<?>, D extends ResourceSupport> implements
ResourceAssembler<T, D> {
public static class EntityId {
private final Object id;
public EntityId(Object id) {
Assert.notNull(id);
this.id = id;
}
public static EntityId id(Object object) {
return new EntityId(object);
}
@Override
public String toString() {
return this.id.toString();
}
}
private final Class<?> controllerClass;
private final Class<D> resourceType;
@@ -77,11 +58,12 @@ public abstract class ResourceAssemblerSupport<T extends Identifiable<?>, D exte
* Converts all given entities into resources.
*
* @see #toResource(Object)
* @param entities
* @param entities must not be {@literal null}.
* @return
*/
public List<D> toResources(Iterable<? extends T> entities) {
Assert.notNull(entities);
List<D> result = new ArrayList<D>();
for (T entity : entities) {
@@ -102,21 +84,21 @@ public abstract class ResourceAssemblerSupport<T extends Identifiable<?>, D exte
}
protected D createResource(T entity, Object... parameters) {
return createResource(entity, EntityId.id(entity.getId()), parameters);
return createResourceWithId(entity.getId(), entity, parameters);
}
/**
* Creates a new resource with a self link to the given id.
*
* @param entity
* @param id
* @param entity must not be {@literal null}.
* @param id must not be {@literal null}.
* @return
*/
protected D createResource(T entity, EntityId id) {
return createResource(entity, id, new Object[0]);
protected D createResourceWithId(Object id, T entity) {
return createResourceWithId(id, entity, new Object[0]);
}
protected D createResource(T entity, EntityId id, Object... parameters) {
protected D createResourceWithId(Object id, T entity, Object... parameters) {
Assert.notNull(entity);
Assert.notNull(id);
@@ -154,4 +136,4 @@ public abstract class ResourceAssemblerSupport<T extends Identifiable<?>, D exte
protected D instantiateResource(T entity) {
return BeanUtils.instantiateClass(resourceType);
}
}
}

View File

@@ -28,7 +28,6 @@ import org.springframework.hateoas.TestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*
* @author Oliver Gierke
*/
public class ControllerLinkBuilderUnitTest extends TestUtils {
@@ -36,7 +35,7 @@ public class ControllerLinkBuilderUnitTest extends TestUtils {
@Test
public void createsLinkToControllerRoot() {
Link link = linkTo(PersonController.class).withSelfRel();
Link link = linkTo(PersonControllerImpl.class).withSelfRel();
assertThat(link.getRel(), is(Link.REL_SELF));
assertThat(link.getHref(), Matchers.endsWith("/people"));
}
@@ -52,7 +51,7 @@ public class ControllerLinkBuilderUnitTest extends TestUtils {
@Test
public void createsLinkToSubResource() {
Link link = linkTo(PersonController.class).slash("something").withSelfRel();
Link link = linkTo(PersonControllerImpl.class).slash("something").withSelfRel();
assertThat(link.getRel(), is(Link.REL_SELF));
assertThat(link.getHref(), Matchers.endsWith("/people/something"));
}
@@ -60,7 +59,7 @@ public class ControllerLinkBuilderUnitTest extends TestUtils {
@Test
public void createsLinkWithCustomRel() {
Link link = linkTo(PersonController.class).withRel(Link.REL_NEXT);
Link link = linkTo(PersonControllerImpl.class).withRel(Link.REL_NEXT);
assertThat(link.getRel(), is(Link.REL_NEXT));
assertThat(link.getHref(), Matchers.endsWith("/people"));
}
@@ -72,7 +71,6 @@ public class ControllerLinkBuilderUnitTest extends TestUtils {
@Test
public void createsLinkToUnmappedController() {
linkTo(UnmappedController.class);
}
@@ -83,17 +81,17 @@ public class ControllerLinkBuilderUnitTest extends TestUtils {
Identifiable<Long> identifyable = mock(Identifiable.class);
when(identifyable.getId()).thenReturn(10L);
Link link = linkTo(PersonController.class).slash(identifyable).withSelfRel();
Link link = linkTo(PersonControllerImpl.class).slash(identifyable).withSelfRel();
assertThat(link.getHref(), Matchers.endsWith("/people/10"));
}
@Test
public void appendingNullIsANoOp() {
Link link = linkTo(PersonController.class).slash(null).withSelfRel();
Link link = linkTo(PersonControllerImpl.class).slash(null).withSelfRel();
assertThat(link.getHref(), Matchers.endsWith("/people"));
link = linkTo(PersonController.class).slash((Object) null).withSelfRel();
link = linkTo(PersonControllerImpl.class).slash((Object) null).withSelfRel();
assertThat(link.getHref(), Matchers.endsWith("/people"));
}
@@ -108,7 +106,11 @@ public class ControllerLinkBuilderUnitTest extends TestUtils {
}
@RequestMapping("/people")
class PersonController {
interface PersonController {
}
class PersonControllerImpl implements PersonController {
}

View File

@@ -18,7 +18,6 @@ package org.springframework.hateoas.mvc;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
import static org.springframework.hateoas.mvc.ResourceAssemblerSupport.EntityId.*;
import java.util.Arrays;
import java.util.List;
@@ -32,6 +31,7 @@ import org.springframework.hateoas.TestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Unit tests for {@link ResourceAssemblerSupport}.
*
* @author Oliver Gierke
*/
@@ -62,7 +62,7 @@ public class ResourceAssemblerSupportUnitTest extends TestUtils {
@Test
public void usesAlternateIdIfGivenExplicitly() {
PersonResource resource = assembler.createResource(person, id(person.alternateId));
PersonResource resource = assembler.createResourceWithId(person.alternateId, person);
Link selfLink = resource.getId();
assertThat(selfLink.getHref(), endsWith("/people/id"));
}