#788 - Fixed obvious warning in all touched files.

* Fixed assertions.
* Removed superfluous code.
* Simplified generics.
* Formatting.
This commit is contained in:
Jens Schauder
2019-01-22 16:05:36 +01:00
committed by Greg Turnquist
parent 4081e58a1f
commit 9f4f1ad79b
27 changed files with 397 additions and 254 deletions

View File

@@ -5,6 +5,70 @@ image:https://spring.io/badges/spring-hateoas/snapshot.svg[http://projects.sprin
This project provides some APIs to ease creating REST representations that follow the http://en.wikipedia.org/wiki/HATEOAS[HATEOAS] principle when working with Spring and especially Spring MVC. The core problem it tries to address is link creation and representation assembly.
== Project Status
We go to great lengths to ensure smooth upgrades. We also seek to make your upgrade on major versions of Java can be as smooth
as possible.
Check the matrix below to see the status of supported versions:
.`master` branch
[cols=4]
|===
| Job | `1.0` status | `0.25` status | `0.x` status
| Test - JDK 8
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%208/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.25.x/jobs/Test%20-%20JDK%208/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas-0.25.x"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.x/jobs/Test%20-%20JDK%208/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas-0.25.x"]
| Test - JDK 8 and Spring 5.0 (snapshots)
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%208%20and%20Spring%205.0%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.25.x/jobs/Test%20-%20JDK%208%20and%20Spring%205.0%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.x/jobs/Test%20-%20JDK%208%20and%20Spring%205.0%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Test - JDK 8 and Spring 5.1 (snapshots)
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%208%20and%20Spring%205.1%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.25.x/jobs/Test%20-%20JDK%208%20and%20Spring%205.1%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.x/jobs/Test%20-%20JDK%208%20and%20Spring%205.1%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Test - JDK 11
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%2011/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Not supported
| Not supported
| Test - JDK 11 and Spring 5.0 (snapshots)
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%2011%20and%20Spring%205.0%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Not supported
| Not supported
| Test - JDK 11 and Spring 5.1 (snapshots)
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%2011%20and%20Spring%205.1%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Not supported
| Not supported
| Test - JDK 12
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%2012/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Not supported
| Not supported
| Test - JDK 12 and Spring 5.0 (snapshots)
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%2012%20and%20Spring%205.0%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Not supported
| Not supported
| Test - JDK 12 and Spring 5.1 (snapshots)
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Test%20-%20JDK%2012%20and%20Spring%205.1%20(snapshots)/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| Not supported
| Not supported
| Build - Release to repo.spring.io
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas/jobs/Build/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.25.x/jobs/Build/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas-0.25.x"]
| image:https://ci.spring.io/api/v1/teams/spring-data/pipelines/spring-hateoas-0.x/jobs/Build/badge[link="https://ci.spring.io/teams/spring-data/pipelines/spring-hateoas-0.25.x"]
|===
== Working with Spring HATEOAS
Since all commits are headlined with its github issue, git will treat it as a comment. To get around this, apply the following configuration to your clone:

View File

@@ -58,7 +58,7 @@ public class Link implements Serializable {
private static final Pattern URI_AND_ATTRIBUTES_PATTERN = Pattern.compile("<(.*)>;(.*)");
private static final Pattern KEY_AND_VALUE_PATTERN = Pattern
.compile("(\\w+)=\"(\\p{Lower}[\\p{Lower}\\p{Digit}\\.\\-\\s]*|" + URI_PATTERN + ")\"");
.compile("(\\w+)=\"(\\p{Lower}[\\p{Lower}\\p{Digit}.\\-\\s]*|" + URI_PATTERN + ")\"");
public static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom";

View File

@@ -54,7 +54,6 @@ public class VndErrors implements Iterable<VndErrors.VndError> {
* Creates a new {@link VndErrors} wrapper for at least one {@link VndError}.
*
* @param errors must not be {@literal null}.
* @param errors
*/
public VndErrors(VndError error, VndError... errors) {

View File

@@ -21,6 +21,7 @@ import lombok.RequiredArgsConstructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.BeansException;
@@ -145,7 +146,7 @@ public class ConverterRegisteringWebMvcConfigurer implements WebMvcConfigurer, B
mapper.setHandlerInstantiator(new UberHandlerInstantiator());
return new TypeConstrainedMappingJackson2HttpMessageConverter(
ResourceSupport.class, Arrays.asList(UBER_JSON), mapper);
ResourceSupport.class, Collections.singletonList(UBER_JSON), mapper);
}
@@ -164,7 +165,7 @@ public class ConverterRegisteringWebMvcConfigurer implements WebMvcConfigurer, B
mapper.setHandlerInstantiator(new CollectionJsonHandlerInstantiator(linkRelationMessageSource));
return new TypeConstrainedMappingJackson2HttpMessageConverter(
ResourceSupport.class, Arrays.asList(COLLECTION_JSON), mapper);
ResourceSupport.class, Collections.singletonList(COLLECTION_JSON), mapper);
}
/**
@@ -186,7 +187,7 @@ public class ConverterRegisteringWebMvcConfigurer implements WebMvcConfigurer, B
this.halFormsConfiguration.getIfAvailable(HalFormsConfiguration::new)));
return new TypeConstrainedMappingJackson2HttpMessageConverter(
ResourceSupport.class, Arrays.asList(HAL_FORMS_JSON), mapper);
ResourceSupport.class, Collections.singletonList(HAL_FORMS_JSON), mapper);
}
/**

View File

@@ -38,7 +38,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
*/
public class AnnotationMappingDiscoverer implements MappingDiscoverer {
private static final Pattern MULTIPLE_SLASHES = Pattern.compile("\\/{2,}");
private static final Pattern MULTIPLE_SLASHES = Pattern.compile("/{2,}");
private final Class<? extends Annotation> annotationType;
private final String mappingAttributeName;

View File

@@ -145,7 +145,7 @@ public class DummyInvocationUtils {
* equips it with an {@link InvocationRecordingMethodInterceptor}. The interceptor records the last invocation and
* returns a proxy of the return type that also implements {@link LastInvocationAware} so that the last method
* invocation can be inspected. Parameters passed to the subsequent method invocation are generally neglected except
* the ones that might be mapped into the URI translation eventually, e.g. {@linke PathVariable} in the case of Spring
* the ones that might be mapped into the URI translation eventually, e.g. {@link org.springframework.web.bind.annotation.PathVariable} in the case of Spring
* MVC. Note, that the return types of the methods have to be capable to be proxied.
*
* @param type must not be {@literal null}.

View File

@@ -75,7 +75,7 @@ public class JsonPathLinkDiscoverer implements LinkDiscoverer {
*
* @param pathTemplate must not be {@literal null} or empty and contain a single placeholder.
* @param mediaType the primary {@link MediaType}s to support.
* @param additional {@link MediaTypes} to support.
* @param others {@link MediaType}s to support.
*/
public JsonPathLinkDiscoverer(String pathTemplate, MediaType mediaType, MediaType... others) {

View File

@@ -81,7 +81,7 @@ public abstract class LinkBuilderSupport<T extends LinkBuilder> implements LinkB
*/
public T slash(Object object) {
object = Optional.class.isInstance(object) ? ((Optional<?>) object).orElse(null) : object;
object = object instanceof Optional ? ((Optional<?>) object).orElse(null) : object;
if (object == null) {
return getThis();

View File

@@ -203,12 +203,12 @@ class HalFormsSerializers {
if (!(model.getHttpMethod() == HttpMethod.GET)) {
validate(resource, affordance, model);
validate(resource, model);
HalFormsTemplate template = HalFormsTemplate.forMethod(model.getHttpMethod()) //
.withProperties(model.getInputProperties());
/**
/*
* First template in HAL-FORMS is "default".
*/
templates.put(templates.isEmpty() ? "default" : model.getName(), template);
@@ -221,12 +221,11 @@ class HalFormsSerializers {
/**
* Verify that the resource's self link and the affordance's URI have the same relative path.
*
*
* @param resource
* @param affordance
* @param model
*/
private static void validate(ResourceSupport resource, Affordance affordance, HalFormsAffordanceModel model) {
private static void validate(ResourceSupport resource, HalFormsAffordanceModel model) {
String affordanceUri = model.getURI();
String selfLinkUri = resource.getRequiredLink(IanaLinkRelation.SELF.value()).expand().getHref();

View File

@@ -81,7 +81,7 @@ public abstract class IdentifiableResourceAssemblerSupport<T extends Identifiabl
private Object[] unwrapIdentifyables(Object[] values) {
return Arrays.stream(values) //
.map(element -> element instanceof Identifiable ? ((Identifiable<?>) element).getId() : element) //
.map(element -> element instanceof Identifiable ? ((Identifiable<?>) element).getId().get() : element) //
.toArray();
}
}

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
public class JacksonSerializers {
/**
* Custom {@link JsonDeserializer} for Spring's {@link MediaType} using the {@link MediaType#paparseMediaType(String)}
* Custom {@link JsonDeserializer} for Spring's {@link MediaType} using the {@link MediaType#parseMediaType(String)}
* method.
*
* @author Oliver Gierke

View File

@@ -109,7 +109,7 @@ public abstract class ResourceAssemblerSupport<T, D extends ResourceSupport> imp
/**
* Transform a list of {@code T}s into a list of {@link ResourceSupport}s.
*
* @see {@link #toListOfResources()} if you need this transformed list rendered as hypermedia
* @see #toListOfResources() if you need this transformed list rendered as hypermedia
*
* @return
*/
@@ -127,7 +127,7 @@ public abstract class ResourceAssemblerSupport<T, D extends ResourceSupport> imp
/**
* Converts all given entities into resources and wraps the result in a {@link Resources} instance.
*
* @see {@link #toListOfResources()}} and {@link ResourceAssembler#toResource(Object)}
* @see #toListOfResources() and {@link ResourceAssembler#toResource(Object)}
* @return
*/
public Resources<D> toResources() {

View File

@@ -90,7 +90,7 @@ public class ResourceProcessorHandlerMethodReturnValueHandler implements Handler
}
// No post-processable type found - proceed with delegate
if (!ResourceSupport.class.isInstance(value)) {
if (!(value instanceof ResourceSupport)) {
delegate.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
return;
}

View File

@@ -196,7 +196,7 @@ public class ResourceProcessorInvoker {
*
* @param processor must not be {@literal null}.
*/
public DefaultProcessorWrapper(ResourceProcessor<?> processor) {
DefaultProcessorWrapper(ResourceProcessor<?> processor) {
Assert.notNull(processor, "Processor must not be null!");

View File

@@ -73,7 +73,7 @@ public class TypeReferences {
private final Type type;
@SuppressWarnings({ "rawtypes", "deprecation" })
protected SyntheticParameterizedTypeReference() {
SyntheticParameterizedTypeReference() {
Class<? extends SyntheticParameterizedTypeReference> foo = getClass();
Type genericSuperclass = foo.getGenericSuperclass();
@@ -154,7 +154,7 @@ public class TypeReferences {
private final Type rawType;
private final Type[] typeArguments;
public SyntheticParameterizedType(Type rawType, Type... typeArguments) {
SyntheticParameterizedType(Type rawType, Type... typeArguments) {
this.rawType = rawType;
this.typeArguments = typeArguments;

View File

@@ -53,7 +53,6 @@ public class Server implements Closeable {
private final RelProvider relProvider;
private final MultiValueMap<Link, Link> baseResources = new LinkedMultiValueMap<>();
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
public Server() {
@@ -96,6 +95,7 @@ public class Server implements Closeable {
withContentType(MediaTypes.HAL_JSON.toString());
// Sample traversal of HAL docs based on Spring-a-Gram showcase
ResourceLoader resourceLoader = new DefaultResourceLoader();
org.springframework.core.io.Resource springagramRoot = resourceLoader
.getResource("classpath:springagram-root.json");
org.springframework.core.io.Resource springagramItems = resourceLoader
@@ -171,7 +171,7 @@ public class Server implements Closeable {
Object content = resource.getContent();
Class<? extends Object> type = content.getClass();
Class<?> type = content.getClass();
String collectionRel = relProvider.getCollectionResourceRelFor(type);
String singleRel = relProvider.getItemResourceRelFor(type);

View File

@@ -272,7 +272,10 @@ public class CollectionJsonWebMvcIntegrationTest {
try {
return ResponseEntity
.created(
new URI(findOne(newEmployeeId).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
new URI(findOne(newEmployeeId) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse(""))) //
.build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
@@ -285,8 +288,11 @@ public class CollectionJsonWebMvcIntegrationTest {
EMPLOYEES.put(id, employee.getContent());
try {
return ResponseEntity.noContent()
.location(new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
return ResponseEntity.noContent() //
.location(new URI(findOne(id) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse(""))) //
.build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
@@ -311,8 +317,11 @@ public class CollectionJsonWebMvcIntegrationTest {
EMPLOYEES.put(id, newEmployee);
try {
return ResponseEntity.noContent()
.location(new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
return ResponseEntity.noContent() //
.location(new URI(findOne(id) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse(""))) //
.build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());

View File

@@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
@@ -242,6 +243,7 @@ public class Jackson2CollectionJsonIntegrationTest extends AbstractJackson2Marsh
}
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public static class ResourceWithAttributes extends ResourceSupport {

View File

@@ -280,9 +280,9 @@ public class EnableHypermediaSupportIntegrationTest {
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
assertThat(adapter.getMessageConverters().get(0).getSupportedMediaTypes())
.hasSize(1)
.contains(MediaTypes.UBER_JSON);
assertThat(adapter.getMessageConverters().get(0).getSupportedMediaTypes()) //
.hasSize(1) //
.contains(MediaTypes.UBER_JSON);
boolean found = false;
@@ -294,11 +294,11 @@ public class EnableHypermediaSupportIntegrationTest {
AbstractMessageConverterMethodArgumentResolver processor = (AbstractMessageConverterMethodArgumentResolver) resolver;
List<HttpMessageConverter<?>> converters = (List<HttpMessageConverter<?>>) ReflectionTestUtils
.getField(processor, "messageConverters");
.getField(processor, "messageConverters");
assertThat(converters.get(0)).isInstanceOf(TypeConstrainedMappingJackson2HttpMessageConverter.class);
assertThat(converters.get(0).getSupportedMediaTypes())
.hasSize(1)
assertThat(converters.get(0).getSupportedMediaTypes()) //
.hasSize(1) //
.contains(MediaTypes.UBER_JSON);
}
}
@@ -325,8 +325,17 @@ public class EnableHypermediaSupportIntegrationTest {
@Test
public void registersHalFormsHttpMessageConvertersForRestTemplate() {
withContext(HalFormsConfig.class, context -> foo(context, RestTemplate.class, it -> it.getMessageConverters().get(0), converter -> assertThat(converter.getSupportedMediaTypes()) //
.hasSize(1).contains(MediaTypes.HAL_FORMS_JSON)));
withContext( //
HalFormsConfig.class, //
context -> foo( //
context, //
RestTemplate.class, //
it -> it.getMessageConverters().get(0), //
converter -> assertThat(converter.getSupportedMediaTypes()) // //
.hasSize(1) //
.contains(MediaTypes.HAL_FORMS_JSON) //
) //
);
}
private static <T, S> void foo(ApplicationContext context, Class<T> beanType, Function<T, S> extractor,
@@ -383,8 +392,8 @@ public class EnableHypermediaSupportIntegrationTest {
withContext(UberConfig.class, context -> {
RestTemplate template = context.getBean(RestTemplate.class);
assertThat(template.getMessageConverters().get(0).getSupportedMediaTypes())
.hasSize(1)
assertThat(template.getMessageConverters().get(0).getSupportedMediaTypes()) //
.hasSize(1) //
.contains(MediaTypes.UBER_JSON);
});
}
@@ -395,7 +404,15 @@ public class EnableHypermediaSupportIntegrationTest {
@Test
public void configuresDefaultObjectMapperForHalToIgnoreUnknownProperties() {
withContext(HalConfig.class, context -> assertObjectMapper(context, MediaTypes.HAL_JSON, mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse()));
withContext( //
HalConfig.class, //
context -> assertObjectMapper( //
context, //
MediaTypes.HAL_JSON, //
mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) //
.isFalse() //
) //
);
}
/**
@@ -404,23 +421,47 @@ public class EnableHypermediaSupportIntegrationTest {
@Test
public void configuresDefaultObjectMapperForHalFormsToIgnoreUnknownProperties() {
withContext(HalFormsConfig.class, context -> assertObjectMapper(context, MediaTypes.HAL_FORMS_JSON, mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse()));
withContext( //
HalFormsConfig.class, //
context -> assertObjectMapper( //
context, //
MediaTypes.HAL_FORMS_JSON, //
mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) //
.isFalse() //
) //
);
}
@Test
public void configuresDefaultObjectMapperForCollectionJsonToIgnoreUnknownProperties() {
withContext(CollectionJsonConfig.class, context -> assertObjectMapper(context, MediaTypes.COLLECTION_JSON, mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse()));
withContext( //
CollectionJsonConfig.class, //
context -> assertObjectMapper( //
context, //
MediaTypes.COLLECTION_JSON, //
mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) //
.isFalse() //
) //
);
}
@Test
public void configuresDefaultObjectMapperForUberToIgnoreUnknownProperties() {
withContext(UberConfig.class, context -> assertObjectMapper(context, MediaTypes.UBER_JSON, mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse()));
withContext( //
UberConfig.class, //
context -> assertObjectMapper( //
context, //
MediaTypes.UBER_JSON, //
mapper -> assertThat(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) //
.isFalse() //
) //
);
}
@Test
public void verifyDefaultHalConfigurationRendersSingleItemAsSingleItem() {
public void verifyDefaultHalConfigurationRendersSingleItemAsSingleItem() throws JsonProcessingException {
withContext(HalConfig.class, context -> {
@@ -437,10 +478,10 @@ public class EnableHypermediaSupportIntegrationTest {
ResourceSupport resourceSupport = new ResourceSupport();
resourceSupport.add(new Link("localhost").withSelfRel());
assertThatCode(() -> { //
assertThatCode(() -> {
assertThat(it.writeValueAsString(resourceSupport)) //
.isEqualTo("{\"_links\":{\"self\":{\"href\":\"localhost\"}}}");
});
.isEqualTo("{\"_links\":{\"self\":{\"href\":\"localhost\"}}}");
}).doesNotThrowAnyException();
});
});
}
@@ -448,14 +489,19 @@ public class EnableHypermediaSupportIntegrationTest {
@Test
public void verifyRenderSingleLinkAsArrayViaOverridingBean() {
withContext(RenderLinkAsSingleLinksConfig.class, context -> assertObjectMapper(context, MediaTypes.HAL_JSON, mapper -> {
ResourceSupport resourceSupport = new ResourceSupport();
resourceSupport.add(new Link("localhost").withSelfRel());
assertThat(mapper.writeValueAsString(resourceSupport))
.isEqualTo("{\"_links\":{\"self\":[{\"href\":\"localhost\"}]}}");
}));
withContext( //
RenderLinkAsSingleLinksConfig.class, //
context -> assertObjectMapper( //
context, //
MediaTypes.HAL_JSON, //
mapper -> { //
ResourceSupport resourceSupport = new ResourceSupport(); //
resourceSupport.add(new Link("localhost").withSelfRel()); //
assertThat(mapper.writeValueAsString(resourceSupport)) //
.isEqualTo("{\"_links\":{\"self\":[{\"href\":\"localhost\"}]}}"); //
} //
) //
);
}
private static <E extends Exception> void withContext(Class<?> configuration,

View File

@@ -156,10 +156,8 @@ public class HalFormsValidationIntegrationTest {
EMPLOYEES.put(newEmployeeId, employee);
try {
return ResponseEntity.noContent()
.location(
new URI(findOne(newEmployeeId).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
.build();
return ResponseEntity.noContent().location(new URI(findOne(newEmployeeId).getLink(IanaLinkRelation.SELF.value())
.map(link -> link.expand().getHref()).orElse(""))).build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
@@ -171,9 +169,13 @@ public class HalFormsValidationIntegrationTest {
EMPLOYEES.put(id, employee);
try {
return ResponseEntity.noContent()
.location(new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
.build();
return ResponseEntity //
.noContent() //
.location( //
new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse("")) //
).build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
@@ -182,9 +184,7 @@ public class HalFormsValidationIntegrationTest {
@PatchMapping("/employees/{id}")
public ResponseEntity<?> partiallyUpdateEmployee(@RequestBody Employee employee, @PathVariable Integer id) {
Employee oldEmployee = EMPLOYEES.get(id);
Employee newEmployee = oldEmployee;
Employee newEmployee = EMPLOYEES.get(id);
if (employee.getName() != null) {
newEmployee = newEmployee.withName(employee.getName());
@@ -197,8 +197,13 @@ public class HalFormsValidationIntegrationTest {
EMPLOYEES.put(id, newEmployee);
try {
return ResponseEntity.noContent()
.location(new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
return ResponseEntity //
.noContent() //
.location( //
new URI(findOne(id) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse(""))) //
.build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());

View File

@@ -212,8 +212,7 @@ public class HalFormsWebMvcIntegrationTest {
@PatchMapping("/employees/{id}")
public ResponseEntity<?> partiallyUpdateEmployee(@RequestBody Employee employee, @PathVariable Integer id) {
Employee oldEmployee = EMPLOYEES.get(id);
Employee newEmployee = oldEmployee;
Employee newEmployee = EMPLOYEES.get(id);
if (employee.getName() != null) {
newEmployee = newEmployee.withName(employee.getName());

View File

@@ -59,13 +59,17 @@ import com.fasterxml.jackson.databind.SerializationFeature;
*/
public class Jackson2HalFormsIntegrationTest extends AbstractJackson2MarshallingIntegrationTest {
static final Links PAGINATION_LINKS = new Links(new Link("foo", IanaLinkRelation.NEXT.value()), new Link("bar", IanaLinkRelation.PREV.value()));
static final Links PAGINATION_LINKS = new Links( //
new Link("foo", IanaLinkRelation.NEXT.value()), //
new Link("bar", IanaLinkRelation.PREV.value()) //
);
@Before
public void setUpModule() {
mapper.registerModule(new Jackson2HalFormsModule());
mapper.setHandlerInstantiator(new HalFormsHandlerInstantiator(new AnnotationRelProvider(), null, null, true, new HalFormsConfiguration()));
mapper.setHandlerInstantiator(new HalFormsHandlerInstantiator( //
new AnnotationRelProvider(), null, null, true, new HalFormsConfiguration()));
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
}
@@ -76,7 +80,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resourceSupport.add(new Link("localhost"));
assertThat(write(resourceSupport))
.isEqualTo(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())));
}
@Test
@@ -85,8 +89,9 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
ResourceSupport expected = new ResourceSupport();
expected.add(new Link("localhost"));
assertThat(read(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())), ResourceSupport.class))
.isEqualTo(expected);
assertThat(
read(MappingUtils.read(new ClassPathResource("single-link-reference.json", getClass())), ResourceSupport.class))
.isEqualTo(expected);
}
@Test
@@ -97,7 +102,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resourceSupport.add(new Link("localhost2"));
assertThat(write(resourceSupport))
.isEqualTo(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())));
}
@Test
@@ -107,8 +112,9 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
expected.add(new Link("localhost"));
expected.add(new Link("localhost2"));
assertThat(read(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())), ResourceSupport.class))
.isEqualTo(expected);
assertThat(
read(MappingUtils.read(new ClassPathResource("list-link-reference.json", getClass())), ResourceSupport.class))
.isEqualTo(expected);
}
@Test
@@ -117,7 +123,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
Resource<SimplePojo> resource = new Resource<>(new SimplePojo("test1", 1), new Link("localhost"));
assertThat(write(resource))
.isEqualTo(MappingUtils.read(new ClassPathResource("simple-resource-unwrapped.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("simple-resource-unwrapped.json", getClass())));
}
@Test
@@ -143,7 +149,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resources.add(new Link("localhost"));
assertThat(write(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("simple-embedded-resource-reference.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("simple-embedded-resource-reference.json", getClass())));
}
@Test
@@ -174,7 +180,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resources.add(new Link("localhost"));
assertThat(write(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("single-embedded-resource-reference.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("single-embedded-resource-reference.json", getClass())));
}
@Test
@@ -201,7 +207,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resources.add(new Link("localhost"));
assertThat(write(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("multiple-resource-resources.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("multiple-resource-resources.json", getClass())));
}
@Test
@@ -228,7 +234,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resources.add(new Link("localhost"));
assertThat(write(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("annotated-resource-resources.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("annotated-resource-resources.json", getClass())));
}
@Test
@@ -268,7 +274,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
@Test
public void serializesPagedResource() throws Exception {
assertThat(write(setupAnnotatedPagedResources()))
.isEqualTo(MappingUtils.read(new ClassPathResource("annotated-paged-resources.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("annotated-paged-resources.json", getClass())));
}
@Test
@@ -284,11 +290,10 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
@Test
public void rendersCuriesCorrectly() throws Exception {
Resources<Object> resources = new Resources<>(Collections.emptySet(), new Link("foo"),
new Link("bar", "myrel"));
Resources<Object> resources = new Resources<>(Collections.emptySet(), new Link("foo"), new Link("bar", "myrel"));
assertThat(getCuriedObjectMapper().writeValueAsString(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("curied-document.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("curied-document.json", getClass())));
}
@Test
@@ -296,7 +301,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
Resources<Object> resources = new Resources<>(Collections.emptySet());
assertThat(getCuriedObjectMapper().writeValueAsString(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("empty-document.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("empty-document.json", getClass())));
}
@Test
@@ -306,7 +311,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resources.add(new Link("foo"));
assertThat(getCuriedObjectMapper().writeValueAsString(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("single-non-curie-document.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("single-non-curie-document.json", getClass())));
}
@Test
@@ -326,13 +331,13 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
CurieProvider provider = new DefaultCurieProvider("default", new UriTemplate("/doc{?rel}")) {
@Override
public Collection<? extends Object> getCurieInformation(Links links) {
public Collection<?> getCurieInformation(Links links) {
return Arrays.asList(new Curie("foo", "bar"), new Curie("bar", "foo"));
}
};
assertThat(getCuriedObjectMapper(provider, null).writeValueAsString(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("multiple-curies-document.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("multiple-curies-document.json", getClass())));
}
@Test
@@ -345,7 +350,8 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
Resources<Object> resources = new Resources<>(values);
assertThat(write(resources)).isEqualTo(MappingUtils.read(new ClassPathResource("empty-embedded-pojos.json", getClass())));
assertThat(write(resources))
.isEqualTo(MappingUtils.read(new ClassPathResource("empty-embedded-pojos.json", getClass())));
}
@Test
@@ -391,7 +397,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
resource.add(new Link("target", "ns:foobar"));
assertThat(objectMapper.writeValueAsString(resource))
.isEqualTo(MappingUtils.read(new ClassPathResource("link-with-title.json", getClass())));
.isEqualTo(MappingUtils.read(new ClassPathResource("link-with-title.json", getClass())));
}
private static Resources<Resource<SimplePojo>> setupResources() {
@@ -418,8 +424,7 @@ public class Jackson2HalFormsIntegrationTest extends AbstractJackson2Marshalling
content.add(new Resource<>(new SimpleAnnotatedPojo("test1", 1), new Link("localhost")));
content.add(new Resource<>(new SimpleAnnotatedPojo("test2", 2), new Link("localhost")));
return new PagedResources<>(content, new PagedResources.PageMetadata(2, 0, 4),
PAGINATION_LINKS);
return new PagedResources<>(content, new PagedResources.PageMetadata(2, 0, 4), PAGINATION_LINKS);
}
private static ObjectMapper getCuriedObjectMapper() {

View File

@@ -79,7 +79,7 @@ public class ControllerLinkBuilderFactoryUnitTest extends TestUtils {
public void appliesParameterValueIfContributorConfigured() {
ControllerLinkBuilderFactory factory = new ControllerLinkBuilderFactory();
factory.setUriComponentsContributors(Arrays.asList(new SampleUriComponentsContributor()));
factory.setUriComponentsContributors(Collections.singletonList(new SampleUriComponentsContributor()));
SpecialType specialType = new SpecialType();
specialType.parameterValue = "value";

View File

@@ -70,7 +70,7 @@ public class IdentifiableResourceAssemblerSupportUnitTest extends TestUtils {
Optional<Link> selfLink = resource.getId();
assertThat(selfLink.map(Link::getHref)) //
.hasValueSatisfying(it -> assertThat(it.endsWith("/people/id")));
.hasValueSatisfying(it -> assertThat(it).endsWith("/people/id"));
}
@Test
@@ -81,7 +81,7 @@ public class IdentifiableResourceAssemblerSupportUnitTest extends TestUtils {
Optional<Link> selfLink = resource.getId();
assertThat(selfLink.map(Link::getHref)) //
.hasValueSatisfying(it -> assertThat(it.endsWith("/people/id")));
.hasValueSatisfying(it -> assertThat(it).endsWith("/people/10/bar/addresses/10"));
}
/**

View File

@@ -541,8 +541,7 @@ public class MultiMediatypeWebMvcIntegrationTest {
public ResponseEntity<?> partiallyUpdateEmployee(@RequestBody Resource<Employee> employee,
@PathVariable Integer id) {
Employee oldEmployee = EMPLOYEES.get(id);
Employee newEmployee = oldEmployee;
Employee newEmployee = EMPLOYEES.get(id);
if (employee.getContent().getName() != null) {
newEmployee = newEmployee.withName(employee.getContent().getName());

View File

@@ -1,9 +1,5 @@
/*
<<<<<<< HEAD
* Copyright 2015-2017 the original author or authors.
=======
* Copyright 2015 the original author or authors.
>>>>>>> 0c39f92... #482 - Add support for Collection+JSON media type
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -96,41 +96,40 @@ public class UberWebMvcIntegrationTest {
public void singleEmployee() throws Exception {
this.mockMvc.perform(get("/employees/0").accept(MediaTypes.UBER_JSON)) //
.andDo(print())
.andExpect(status().isOk()) //
.andDo(print()) //
.andExpect(status().isOk()) //
.andExpect(jsonPath("$.uber.version", is("1.0")))
.andExpect(jsonPath("$.uber.version", is("1.0")))
.andExpect(jsonPath("$.uber.data.*", hasSize(5)))
.andExpect(jsonPath("$.uber.data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[1]", is("findOne")))
.andExpect(jsonPath("$.uber.data[0].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data.*", hasSize(5))) //
.andExpect(jsonPath("$.uber.data[0].name", is("self"))) //
.andExpect(jsonPath("$.uber.data[0].rel[0]", is("self"))) //
.andExpect(jsonPath("$.uber.data[0].rel[1]", is("findOne"))) //
.andExpect(jsonPath("$.uber.data[0].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[1].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[1].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[3].name", is("employees")))
.andExpect(jsonPath("$.uber.data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[3].name", is("employees")))
.andExpect(jsonPath("$.uber.data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[4].data.*", hasSize(2)))
.andExpect(jsonPath("$.uber.data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[4].data[0].value", is("ring bearer")))
.andExpect(jsonPath("$.uber.data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[4].data[1].value", is("Frodo Baggins")))
;
.andExpect(jsonPath("$.uber.data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[4].data.*", hasSize(2)))
.andExpect(jsonPath("$.uber.data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[4].data[0].value", is("ring bearer")))
.andExpect(jsonPath("$.uber.data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[4].data[1].value", is("Frodo Baggins")));
}
/**
@@ -140,78 +139,77 @@ public class UberWebMvcIntegrationTest {
public void collectionOfEmployees() throws Exception {
this.mockMvc.perform(get("/employees").accept(MediaTypes.UBER_JSON)) //
.andDo(print())
.andExpect(status().isOk()) //
.andDo(print()) //
.andExpect(status().isOk()) //
.andExpect(jsonPath("$.uber.version", is("1.0")))
.andExpect(jsonPath("$.uber.version", is("1.0")))
.andExpect(jsonPath("$.uber.data.*", hasSize(4)))
.andExpect(jsonPath("$.uber.data.*", hasSize(4)))
.andExpect(jsonPath("$.uber.data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[0].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[0].name", is("self"))) //
.andExpect(jsonPath("$.uber.data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[0].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[1].name", is("newEmployee")))
.andExpect(jsonPath("$.uber.data[1].rel[0]", is("newEmployee")))
.andExpect(jsonPath("$.uber.data[1].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[1].action", is("append")))
.andExpect(jsonPath("$.uber.data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[1].name", is("newEmployee")))
.andExpect(jsonPath("$.uber.data[1].rel[0]", is("newEmployee")))
.andExpect(jsonPath("$.uber.data[1].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[1].action", is("append")))
.andExpect(jsonPath("$.uber.data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[2].data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[2].data[0].rel[1]", is("findOne")))
.andExpect(jsonPath("$.uber.data[2].data[0].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[2].data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[2].data[0].rel[1]", is("findOne")))
.andExpect(jsonPath("$.uber.data[2].data[0].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[1].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[2].data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[1].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[2].data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[2].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[2].data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].data[2].url", is("http://localhost/employees/0")))
.andExpect(jsonPath("$.uber.data[2].data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[2].data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[2].data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[2].data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[2].data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[2].data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[2].data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[2].data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[0].value", is("ring bearer")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[1].value", is("Frodo Baggins")))
.andExpect(jsonPath("$.uber.data[2].data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[0].value", is("ring bearer")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[2].data[4].data[1].value", is("Frodo Baggins")))
.andExpect(jsonPath("$.uber.data[3].data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[3].data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[3].data[0].rel[1]", is("findOne")))
.andExpect(jsonPath("$.uber.data[3].data[0].url", is("http://localhost/employees/1")))
.andExpect(jsonPath("$.uber.data[3].data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[3].data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[3].data[0].rel[1]", is("findOne")))
.andExpect(jsonPath("$.uber.data[3].data[0].url", is("http://localhost/employees/1")))
.andExpect(jsonPath("$.uber.data[3].data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[1].url", is("http://localhost/employees/1")))
.andExpect(jsonPath("$.uber.data[3].data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[3].data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[3].data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[1].url", is("http://localhost/employees/1")))
.andExpect(jsonPath("$.uber.data[3].data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[3].data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[3].data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[2].url", is("http://localhost/employees/1")))
.andExpect(jsonPath("$.uber.data[3].data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[3].data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[3].data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[3].data[2].url", is("http://localhost/employees/1")))
.andExpect(jsonPath("$.uber.data[3].data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[3].data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[3].data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[3].data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[3].data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[3].data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[3].data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[3].data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[3].data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[0].value", is("burglar")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[1].value", is("Bilbo Baggins")))
;
.andExpect(jsonPath("$.uber.data[3].data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[0].value", is("burglar")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[3].data[4].data[1].value", is("Bilbo Baggins")));
}
/**
@@ -222,49 +220,48 @@ public class UberWebMvcIntegrationTest {
String input = read(new ClassPathResource("create-employee.json", getClass()));
this.mockMvc.perform(post("/employees")
.content(input)
.contentType(MediaTypes.UBER_JSON))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(header().stringValues(HttpHeaders.LOCATION, "http://localhost/employees/2"));
this.mockMvc.perform(post("/employees") //
.content(input) //
.contentType(MediaTypes.UBER_JSON)) //
.andDo(print()) //
.andExpect(status().isCreated()) //
.andExpect(header().stringValues(HttpHeaders.LOCATION, "http://localhost/employees/2"));
this.mockMvc.perform(get("/employees/2").accept(MediaTypes.UBER_JSON))
.andDo(print())
.andExpect(status().isOk()) //
this.mockMvc.perform(get("/employees/2").accept(MediaTypes.UBER_JSON)) //
.andDo(print()) //
.andExpect(status().isOk())
.andExpect(jsonPath("$.uber.version", is("1.0")))
.andExpect(jsonPath("$.uber.version", is("1.0")))
.andExpect(jsonPath("$.uber.data.*", hasSize(5)))
.andExpect(jsonPath("$.uber.data[0].name", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[0]", is("self")))
.andExpect(jsonPath("$.uber.data[0].rel[1]", is("findOne")))
.andExpect(jsonPath("$.uber.data[0].url", is("http://localhost/employees/2")))
.andExpect(jsonPath("$.uber.data.*", hasSize(5))) //
.andExpect(jsonPath("$.uber.data[0].name", is("self"))) //
.andExpect(jsonPath("$.uber.data[0].rel[0]", is("self"))) //
.andExpect(jsonPath("$.uber.data[0].rel[1]", is("findOne"))) //
.andExpect(jsonPath("$.uber.data[0].url", is("http://localhost/employees/2")))
.andExpect(jsonPath("$.uber.data[1].name", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[1].rel[0]", is("updateEmployee")))
.andExpect(jsonPath("$.uber.data[1].url", is("http://localhost/employees/2")))
.andExpect(jsonPath("$.uber.data[1].action", is("replace")))
.andExpect(jsonPath("$.uber.data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[1].name", is("updateEmployee"))) //
.andExpect(jsonPath("$.uber.data[1].rel[0]", is("updateEmployee"))) //
.andExpect(jsonPath("$.uber.data[1].url", is("http://localhost/employees/2"))) //
.andExpect(jsonPath("$.uber.data[1].action", is("replace"))) //
.andExpect(jsonPath("$.uber.data[1].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].name", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].rel[0]", is("partiallyUpdateEmployee")))
.andExpect(jsonPath("$.uber.data[2].url", is("http://localhost/employees/2")))
.andExpect(jsonPath("$.uber.data[2].action", is("partial")))
.andExpect(jsonPath("$.uber.data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[2].name", is("partiallyUpdateEmployee"))) //
.andExpect(jsonPath("$.uber.data[2].rel[0]", is("partiallyUpdateEmployee"))) //
.andExpect(jsonPath("$.uber.data[2].url", is("http://localhost/employees/2"))) //
.andExpect(jsonPath("$.uber.data[2].action", is("partial"))) //
.andExpect(jsonPath("$.uber.data[2].model", is("name={name}&role={role}")))
.andExpect(jsonPath("$.uber.data[3].name", is("employees")))
.andExpect(jsonPath("$.uber.data[3].rel[0]", is("employees")))
.andExpect(jsonPath("$.uber.data[3].rel[1]", is("all")))
.andExpect(jsonPath("$.uber.data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[3].name", is("employees"))) //
.andExpect(jsonPath("$.uber.data[3].rel[0]", is("employees"))) //
.andExpect(jsonPath("$.uber.data[3].rel[1]", is("all"))) //
.andExpect(jsonPath("$.uber.data[3].url", is("http://localhost/employees")))
.andExpect(jsonPath("$.uber.data[4].name", is("employee")))
.andExpect(jsonPath("$.uber.data[4].data.*", hasSize(2)))
.andExpect(jsonPath("$.uber.data[4].data[0].name", is("role")))
.andExpect(jsonPath("$.uber.data[4].data[0].value", is("gardener")))
.andExpect(jsonPath("$.uber.data[4].data[1].name", is("name")))
.andExpect(jsonPath("$.uber.data[4].data[1].value", is("Samwise Gamgee")))
;
.andExpect(jsonPath("$.uber.data[4].name", is("employee"))) //
.andExpect(jsonPath("$.uber.data[4].data.*", hasSize(2))) //
.andExpect(jsonPath("$.uber.data[4].data[0].name", is("role"))) //
.andExpect(jsonPath("$.uber.data[4].data[0].value", is("gardener"))) //
.andExpect(jsonPath("$.uber.data[4].data[1].name", is("name"))) //
.andExpect(jsonPath("$.uber.data[4].data[1].value", is("Samwise Gamgee")));
}
@RestController
@@ -282,32 +279,33 @@ public class UberWebMvcIntegrationTest {
}
// Generate an "Affordance" based on this method (the "self" link)
Link selfLink = linkTo(methodOn(EmployeeController.class).all()).withSelfRel()
.andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null)))
.andAffordance(afford(methodOn(EmployeeController.class).search(null, null)));
Link selfLink = linkTo(methodOn(EmployeeController.class).all()).withSelfRel() //
.andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null))) //
.andAffordance(afford(methodOn(EmployeeController.class).search(null, null)));
// Return the collection of employee resources along with the composite affordance
return new Resources<>(employees, selfLink);
}
@GetMapping("/employees/search")
public Resources<Resource<Employee>> search(@RequestParam(value="name", required=false) String name,
@RequestParam(value="role", required=false) String role) {
public Resources<Resource<Employee>> search(@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "role", required = false) String role) {
// Create a list of Resource<Employee>'s to return
List<Resource<Employee>> employees = new ArrayList<>();
// Fetch each Resource<Employee> using the controller's findOne method.
for (int i = 0; i < EMPLOYEES.size(); i++) {
Resource<Employee> employeeResource = findOne(i);
boolean nameMatches = Optional.ofNullable(name)
.map(s -> employeeResource.getContent().getName().contains(s))
.orElse(true);
boolean nameMatches = Optional.ofNullable(name) //
.map(s -> employeeResource.getContent().getName().contains(s)) //
.orElse(true);
boolean roleMatches = Optional.ofNullable(role)
.map( s -> employeeResource.getContent().getRole().contains(s))
.orElse(true);
boolean roleMatches = Optional.ofNullable(role) //
.map(s -> employeeResource.getContent().getRole().contains(s)) //
.orElse(true);
if (nameMatches && roleMatches) {
employees.add(employeeResource);
@@ -315,9 +313,10 @@ public class UberWebMvcIntegrationTest {
}
// Generate an "Affordance" based on this method (the "self" link)
Link selfLink = linkTo(methodOn(EmployeeController.class).all()).withSelfRel()
.andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null)))
.andAffordance(afford(methodOn(EmployeeController.class).search(null, null)));
Link selfLink = linkTo(methodOn(EmployeeController.class).all()) //
.withSelfRel() //
.andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null))) //
.andAffordance(afford(methodOn(EmployeeController.class).search(null, null)));
// Return the collection of employee resources along with the composite affordance
return new Resources<>(employees, selfLink);
@@ -333,11 +332,11 @@ public class UberWebMvcIntegrationTest {
Link employeesLink = linkTo(methodOn(EmployeeController.class).all()).withRel("employees");
// Return the affordance + a link back to the entire collection resource.
return new Resource<>(EMPLOYEES.get(id),
findOneLink
.andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, id))) //
.andAffordance(afford(methodOn(EmployeeController.class).partiallyUpdateEmployee(null, id))),
employeesLink);
return new Resource<>(EMPLOYEES.get(id), //
findOneLink //
.andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, id))) // //
.andAffordance(afford(methodOn(EmployeeController.class).partiallyUpdateEmployee(null, id))), //
employeesLink);
}
@PostMapping("/employees")
@@ -348,8 +347,13 @@ public class UberWebMvcIntegrationTest {
EMPLOYEES.put(newEmployeeId, employee.getContent());
try {
return ResponseEntity.created(new URI(findOne(newEmployeeId).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
.build();
return ResponseEntity.created( //
new URI(findOne(newEmployeeId) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse("") //
) //
).build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
@@ -361,15 +365,23 @@ public class UberWebMvcIntegrationTest {
EMPLOYEES.put(id, employee.getContent());
try {
return ResponseEntity.noContent().location(new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
.build();
return ResponseEntity //
.noContent() //
.location( //
new URI(findOne(id) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse("") //
) //
).build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
@PatchMapping("/employees/{id}")
public ResponseEntity<?> partiallyUpdateEmployee(@RequestBody Resource<Employee> employee, @PathVariable Integer id) {
public ResponseEntity<?> partiallyUpdateEmployee(@RequestBody Resource<Employee> employee,
@PathVariable Integer id) {
Employee oldEmployee = EMPLOYEES.get(id);
Employee newEmployee = oldEmployee;
@@ -385,8 +397,15 @@ public class UberWebMvcIntegrationTest {
EMPLOYEES.put(id, newEmployee);
try {
return ResponseEntity.noContent().location(new URI(findOne(id).getLink(IanaLinkRelation.SELF.value()).map(link -> link.expand().getHref()).orElse("")))
.build();
return ResponseEntity //
.noContent() //
.location( //
new URI(findOne(id) //
.getLink(IanaLinkRelation.SELF.value()) //
.map(link -> link.expand().getHref()) //
.orElse("") //
) //
).build();
} catch (URISyntaxException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
@@ -395,7 +414,7 @@ public class UberWebMvcIntegrationTest {
@Configuration
@EnableWebMvc
@EnableHypermediaSupport(type = { HypermediaType.UBER})
@EnableHypermediaSupport(type = { HypermediaType.UBER })
static class TestConfig {
@Bean
@@ -403,4 +422,4 @@ public class UberWebMvcIntegrationTest {
return new EmployeeController();
}
}
}
}