DATAREST-837 - Move to ResourceProcessor invcation infrastructure in Spring HATEOAS.
Deprecated the ResourceProcessor invoking infrastructure in place here in favor of the types moved to Spring HATEOAS. Refactored our codebase to make use of these newly introduced types right away. Related tickets: spring-projects/spring-hateoas#362.
This commit is contained in:
@@ -40,7 +40,6 @@ import org.springframework.data.rest.core.support.DefaultSelfLinkProvider;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
import org.springframework.data.rest.webmvc.ResourceProcessorInvoker;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.LookupObjectSerializer;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.NestedEntitySerializer;
|
||||
@@ -58,6 +57,7 @@ import org.springframework.hateoas.RelProvider;
|
||||
import org.springframework.hateoas.ResourceProcessor;
|
||||
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule;
|
||||
import org.springframework.hateoas.mvc.ResourceProcessorInvoker;
|
||||
import org.springframework.plugin.core.OrderAwarePluginRegistry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.springframework.data.rest.core.support.DefaultSelfLinkProvider;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
import org.springframework.data.rest.webmvc.ResourceProcessorInvoker;
|
||||
import org.springframework.data.rest.webmvc.jpa.Person;
|
||||
import org.springframework.data.rest.webmvc.jpa.PersonRepository;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.LookupObjectSerializer;
|
||||
@@ -59,6 +58,7 @@ import org.springframework.hateoas.RelProvider;
|
||||
import org.springframework.hateoas.ResourceProcessor;
|
||||
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule;
|
||||
import org.springframework.hateoas.mvc.ResourceProcessorInvoker;
|
||||
import org.springframework.plugin.core.OrderAwarePluginRegistry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,20 +30,22 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
|
||||
* their Spring MVC context.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class RepositoryRestHandlerAdapter extends ResourceProcessorInvokingHandlerAdapter {
|
||||
public class RepositoryRestHandlerAdapter
|
||||
extends org.springframework.hateoas.mvc.ResourceProcessorInvokingHandlerAdapter {
|
||||
|
||||
private final List<HandlerMethodArgumentResolver> argumentResolvers;
|
||||
|
||||
/**
|
||||
* Creates a new {@link RepositoryRestHandlerAdapter} using the given {@link HandlerMethodArgumentResolver} and
|
||||
* {@link ResourceProcessorInvoker}.
|
||||
* {@link org.springframework.hateoas.mvc.ResourceProcessorInvoker}.
|
||||
*
|
||||
* @param argumentResolvers must not be {@literal null}.
|
||||
* @param invoker must not be {@literal null}.
|
||||
*/
|
||||
public RepositoryRestHandlerAdapter(List<HandlerMethodArgumentResolver> argumentResolvers,
|
||||
ResourceProcessorInvoker invoker) {
|
||||
org.springframework.hateoas.mvc.ResourceProcessorInvoker invoker) {
|
||||
|
||||
super(invoker);
|
||||
this.argumentResolvers = argumentResolvers;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,7 +39,9 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* configured {@link ResourceProcessor}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @deprecated use the same type from Spring HATEOAS, will be removed in 2.7.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiredArgsConstructor
|
||||
public class ResourceProcessorHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
|
||||
|
||||
@@ -38,7 +38,9 @@ import org.springframework.util.ReflectionUtils;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 2.5
|
||||
* @deprecated use the same type from Spring HATEOAS, will be removed in 2.7.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ResourceProcessorInvoker {
|
||||
|
||||
private final List<ProcessorWrapper> processors;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,9 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Phil Webb
|
||||
* @deprecated use the same type from Spring HATEOAS, will be removed in 2.7.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ResourceProcessorInvokingHandlerAdapter extends RequestMappingHandlerAdapter {
|
||||
|
||||
private static final Method RETURN_VALUE_HANDLER_METHOD = ReflectionUtils
|
||||
|
||||
@@ -81,7 +81,6 @@ import org.springframework.data.rest.webmvc.RepositoryRestController;
|
||||
import org.springframework.data.rest.webmvc.RepositoryRestExceptionHandler;
|
||||
import org.springframework.data.rest.webmvc.RepositoryRestHandlerAdapter;
|
||||
import org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping;
|
||||
import org.springframework.data.rest.webmvc.ResourceProcessorInvoker;
|
||||
import org.springframework.data.rest.webmvc.RestMediaTypes;
|
||||
import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResolver;
|
||||
import org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter;
|
||||
@@ -127,6 +126,7 @@ import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule.HalHandlerInstantiator;
|
||||
import org.springframework.hateoas.mvc.ResourceProcessorInvoker;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
@@ -845,7 +845,6 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
|
||||
RepositoryEntityLinks entityLinks = entityLinks();
|
||||
MessageSourceAccessor messageSourceAccessor = resourceDescriptionMessageSourceAccessor();
|
||||
RepositoryRestConfiguration config = config();
|
||||
ResourceMappings resourceMappings = resourceMappings();
|
||||
|
||||
return new RootResourceInformationToAlpsDescriptorConverter(associationLinks(), repositories, persistentEntities,
|
||||
entityLinks, messageSourceAccessor, config, objectMapper(), enumTranslator());
|
||||
|
||||
@@ -43,13 +43,13 @@ import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
import org.springframework.data.rest.webmvc.PersistentEntityResource;
|
||||
import org.springframework.data.rest.webmvc.ResourceProcessorInvoker;
|
||||
import org.springframework.data.rest.webmvc.mapping.Associations;
|
||||
import org.springframework.data.rest.webmvc.mapping.LinkCollector;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Links;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.UriTemplate;
|
||||
import org.springframework.hateoas.mvc.ResourceProcessorInvoker;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -148,7 +148,6 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
*
|
||||
* @param entities must not be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private PersistentEntityResourceSerializer(LinkCollector collector) {
|
||||
|
||||
super(PersistentEntityResource.class);
|
||||
|
||||
@@ -1,452 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.rest.webmvc.HttpEntityMatcher.*;
|
||||
import static org.springframework.util.ReflectionUtils.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.rest.webmvc.ResourceProcessorInvoker.ResourcesProcessorWrapper;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.PagedResources;
|
||||
import org.springframework.hateoas.PagedResources.PageMetadata;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.ResourceProcessor;
|
||||
import org.springframework.hateoas.Resources;
|
||||
import org.springframework.hateoas.core.EmbeddedWrappers;
|
||||
import org.springframework.hateoas.mvc.HeaderLinksResponseEntity;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.ReflectionUtils.MethodCallback;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.springframework.data.rest.webmvc.ResourceProcessorHandlerMethodReturnValueHandler}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ResourceProcessorHandlerMethodReturnValueHandlerUnitTests {
|
||||
|
||||
static final Resource<String> FOO = new Resource<String>("foo");
|
||||
static final Resources<Resource<String>> FOOS = new Resources<Resource<String>>(Collections.singletonList(FOO));
|
||||
static final PagedResources<Resource<String>> FOO_PAGE = new PagedResources<Resource<String>>(
|
||||
Collections.singleton(FOO), new PageMetadata(1, 0, 10));
|
||||
static final StringResource FOO_RES = new StringResource("foo");
|
||||
static final HttpEntity<Resource<String>> FOO_ENTITY = new HttpEntity<Resource<String>>(FOO);
|
||||
static final ResponseEntity<Resource<String>> FOO_RESP_ENTITY = new ResponseEntity<Resource<String>>(FOO,
|
||||
HttpStatus.OK);
|
||||
static final HttpEntity<StringResource> FOO_RES_ENTITY = new HttpEntity<StringResource>(FOO_RES);
|
||||
static final Resource<String> BAR = new Resource<String>("bar");
|
||||
static final Resources<Resource<String>> BARS = new Resources<Resource<String>>(Collections.singletonList(BAR));
|
||||
static final StringResource BAR_RES = new StringResource("bar");
|
||||
static final HttpEntity<Resource<String>> BAR_ENTITY = new HttpEntity<Resource<String>>(BAR);
|
||||
static final ResponseEntity<Resource<String>> BAR_RESP_ENTITY = new ResponseEntity<Resource<String>>(BAR,
|
||||
HttpStatus.OK);
|
||||
static final HttpEntity<StringResource> BAR_RES_ENTITY = new HttpEntity<StringResource>(BAR_RES);
|
||||
static final Resource<Long> LONG_10 = new Resource<Long>(10L);
|
||||
static final Resource<Long> LONG_20 = new Resource<Long>(20L);
|
||||
static final LongResource LONG_10_RES = new LongResource(10L);
|
||||
static final LongResource LONG_20_RES = new LongResource(20L);
|
||||
static final HttpEntity<Resource<Long>> LONG_10_ENTITY = new HttpEntity<Resource<Long>>(LONG_10);
|
||||
static final HttpEntity<LongResource> LONG_10_RES_ENTITY = new HttpEntity<LongResource>(LONG_10_RES);
|
||||
static final HttpEntity<Resource<Long>> LONG_20_ENTITY = new HttpEntity<Resource<Long>>(LONG_20);
|
||||
static final HttpEntity<LongResource> LONG_20_RES_ENTITY = new HttpEntity<LongResource>(LONG_20_RES);
|
||||
static final Map<String, MethodParameter> METHOD_PARAMS = new HashMap<String, MethodParameter>();
|
||||
|
||||
static {
|
||||
doWithMethods(Controller.class, new MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
METHOD_PARAMS.put(method.getName(), new MethodParameter(method, -1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Mock HandlerMethodReturnValueHandler delegate;
|
||||
List<ResourceProcessor<?>> resourceProcessors;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
resourceProcessors = new ArrayList<ResourceProcessor<?>>();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsIfDelegateSupports() {
|
||||
assertSupport(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotSupportIfDelegateDoesNot() {
|
||||
assertSupport(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesStringResource() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("stringResourceEntity", is(BAR), FOO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesStringResourceInResponseEntity() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("stringResourceEntity", httpEntity(BAR_RESP_ENTITY), FOO_RESP_ENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesStringResourceInWildcardResponseEntity() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("resourceEntity", httpEntity(BAR_RESP_ENTITY), FOO_RESP_ENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesStringResources() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourcesProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("resources", is(BARS), FOOS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesSpecializedStringResource() throws Exception {
|
||||
|
||||
resourceProcessors.add(SpecializedStringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("stringResourceEntity", httpEntity(BAR_RES_ENTITY), FOO_RES_ENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesSpecializedStringUsingStringResourceProcessor() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("specializedStringResourceEntity", httpEntity(BAR_ENTITY), FOO_RES_ENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesLongResource() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("longResource", is(LONG_20), LONG_10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesSpecializedLongResource() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(SpecializedLongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("specializedLongResourceEntity", httpEntity(LONG_20_RES_ENTITY), LONG_10_RES_ENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotPostProcesseLongResourceWithSpecializedLongResourceProcessor() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(SpecializedLongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("numberResourceEntity", httpEntity(LONG_10_ENTITY), LONG_10_ENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessesSpecializedLongResourceUsingLongResourceProcessor() throws Exception {
|
||||
|
||||
resourceProcessors.add(StringResourceProcessor.INSTANCE);
|
||||
resourceProcessors.add(LongResourceProcessor.INSTANCE);
|
||||
|
||||
invokeReturnValueHandler("resourceEntity", is(LONG_20), LONG_10_RES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesHeaderLinksResponseEntityIfConfigured() throws Exception {
|
||||
|
||||
Resource<String> resource = new Resource<String>("foo", new Link("href", "rel"));
|
||||
MethodParameter parameter = METHOD_PARAMS.get("resource");
|
||||
|
||||
ResourceProcessorHandlerMethodReturnValueHandler handler = new ResourceProcessorHandlerMethodReturnValueHandler(
|
||||
delegate, new ResourceProcessorInvoker(resourceProcessors));
|
||||
handler.setRootLinksAsHeaders(true);
|
||||
handler.handleReturnValue(resource, parameter, null, null);
|
||||
|
||||
verify(delegate, times(1)).handleReturnValue(Mockito.any(HeaderLinksResponseEntity.class), eq(parameter),
|
||||
Mockito.any(ModelAndViewContainer.class), Mockito.any(NativeWebRequest.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-331
|
||||
*/
|
||||
@Test
|
||||
public void resourcesProcessorMatchesValueSubTypes() {
|
||||
|
||||
ResolvableType type = ResolvableType.forClass(PagedStringResources.class);
|
||||
|
||||
assertThat(ResourcesProcessorWrapper.isValueTypeMatch(FOO_PAGE, type), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-331
|
||||
*/
|
||||
@Test
|
||||
public void invokesProcessorsForProjection() throws Exception {
|
||||
|
||||
ProjectionProcessor projectionProcessor = new ProjectionProcessor();
|
||||
resourceProcessors.add(projectionProcessor);
|
||||
|
||||
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
|
||||
SampleProjection projection = factory.createProjection(SampleProjection.class, new Sample());
|
||||
Resource<SampleProjection> resource = new Resource<SampleProjection>(projection);
|
||||
|
||||
invokeReturnValueHandler("object", is(resource), resource);
|
||||
assertThat(projectionProcessor.invoked, is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-331
|
||||
*/
|
||||
@Test
|
||||
public void doesNotMatchOnNonMatchingResourcesTypes() throws Exception {
|
||||
|
||||
Resource<Object> resource = new Resource<Object>(new Object());
|
||||
PagedResources<Resource<Object>> pagedResources = new PagedResources<Resource<Object>>(
|
||||
Collections.singleton(resource), new PageMetadata(1, 0, 10));
|
||||
|
||||
ResolvableType type = ResolvableType.forClass(RepositoryLinksResource.class);
|
||||
|
||||
assertThat(ResourcesProcessorWrapper.isValueTypeMatch(pagedResources, type), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-479
|
||||
*/
|
||||
@Test
|
||||
public void doesNotInvokeAProcessorForASpecializedType() throws Exception {
|
||||
|
||||
EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
|
||||
Resources<Object> value = new Resources<Object>(
|
||||
Collections.<Object> singleton(wrappers.emptyCollectionOf(Object.class)));
|
||||
ResourcesProcessorWrapper wrapper = new ResourcesProcessorWrapper(new SpecialResourcesProcessor());
|
||||
|
||||
ResolvableType type = ResolvableType.forMethodReturnType(Controller.class.getMethod("resourcesOfObject"));
|
||||
|
||||
assertThat(wrapper.supports(type, value), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-702
|
||||
*/
|
||||
@Test
|
||||
public void registersProcessorForProxyType() {
|
||||
|
||||
ProjectionProcessor processor = new ProjectionProcessor();
|
||||
ProxyFactory factory = new ProxyFactory(processor);
|
||||
|
||||
resourceProcessors.add((ResourceProcessor<?>) factory.getProxy());
|
||||
|
||||
new ResourceProcessorHandlerMethodReturnValueHandler(delegate, new ResourceProcessorInvoker(resourceProcessors));
|
||||
}
|
||||
|
||||
// Helpers ---------------------------------------------------------//
|
||||
private void invokeReturnValueHandler(String method, final Matcher<?> matcher, Object returnValue) throws Exception {
|
||||
final MethodParameter methodParam = METHOD_PARAMS.get(method);
|
||||
|
||||
if (methodParam == null) {
|
||||
throw new IllegalArgumentException("Invalid method!");
|
||||
}
|
||||
|
||||
HandlerMethodReturnValueHandler handler = new ResourceProcessorHandlerMethodReturnValueHandler(delegate,
|
||||
new ResourceProcessorInvoker(resourceProcessors));
|
||||
handler.handleReturnValue(returnValue, methodParam, null, null);
|
||||
}
|
||||
|
||||
private void assertSupport(boolean value) {
|
||||
|
||||
final MethodParameter parameter = Mockito.mock(MethodParameter.class);
|
||||
when(delegate.supportsReturnType(Mockito.any(MethodParameter.class))).thenReturn(value);
|
||||
|
||||
HandlerMethodReturnValueHandler handler = new ResourceProcessorHandlerMethodReturnValueHandler(delegate,
|
||||
new ResourceProcessorInvoker(resourceProcessors));
|
||||
|
||||
assertThat(handler.supportsReturnType(parameter), is(value));
|
||||
}
|
||||
|
||||
enum StringResourceProcessor implements ResourceProcessor<Resource<String>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Resource<String> process(Resource<String> resource) {
|
||||
return BAR;
|
||||
}
|
||||
}
|
||||
|
||||
enum LongResourceProcessor implements ResourceProcessor<Resource<Long>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Resource<Long> process(Resource<Long> resource) {
|
||||
return LONG_20;
|
||||
}
|
||||
}
|
||||
|
||||
enum StringResourcesProcessor implements ResourceProcessor<Resources<Resource<String>>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Resources<Resource<String>> process(Resources<Resource<String>> resource) {
|
||||
return BARS;
|
||||
}
|
||||
}
|
||||
|
||||
enum SpecializedStringResourceProcessor implements ResourceProcessor<StringResource> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public StringResource process(StringResource resource) {
|
||||
return BAR_RES;
|
||||
}
|
||||
}
|
||||
|
||||
enum SpecializedLongResourceProcessor implements ResourceProcessor<LongResource> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public LongResource process(LongResource resource) {
|
||||
return LONG_20_RES;
|
||||
}
|
||||
}
|
||||
|
||||
static interface Controller {
|
||||
|
||||
Resources<Resource<String>> resources();
|
||||
|
||||
Resource<String> resource();
|
||||
|
||||
Resource<Long> longResource();
|
||||
|
||||
StringResource specializedResource();
|
||||
|
||||
Object object();
|
||||
|
||||
HttpEntity<Resource<?>> resourceEntity();
|
||||
|
||||
HttpEntity<Resources<?>> resourcesEntity();
|
||||
|
||||
HttpEntity<Object> objectEntity();
|
||||
|
||||
HttpEntity<Resource<String>> stringResourceEntity();
|
||||
|
||||
HttpEntity<Resource<? extends Number>> numberResourceEntity();
|
||||
|
||||
HttpEntity<StringResource> specializedStringResourceEntity();
|
||||
|
||||
HttpEntity<LongResource> specializedLongResourceEntity();
|
||||
|
||||
ResponseEntity<Resource<?>> resourceResponseEntity();
|
||||
|
||||
ResponseEntity<Resources<?>> resourcesResponseEntity();
|
||||
|
||||
Resources<Object> resourcesOfObject();
|
||||
}
|
||||
|
||||
static class StringResource extends Resource<String> {
|
||||
public StringResource(String value) {
|
||||
super(value);
|
||||
}
|
||||
}
|
||||
|
||||
static class LongResource extends Resource<Long> {
|
||||
public LongResource(Long value) {
|
||||
super(value);
|
||||
}
|
||||
}
|
||||
|
||||
static class PagedStringResources extends PagedResources<Resource<String>> {};
|
||||
|
||||
static class Sample {
|
||||
|
||||
}
|
||||
|
||||
static interface SampleProjection {
|
||||
|
||||
}
|
||||
|
||||
static class ProjectionProcessor implements ResourceProcessor<Resource<SampleProjection>> {
|
||||
|
||||
boolean invoked = false;
|
||||
|
||||
@Override
|
||||
public Resource<SampleProjection> process(Resource<SampleProjection> resource) {
|
||||
this.invoked = true;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
static class SpecialResources extends Resources<Object> {
|
||||
public SpecialResources() {
|
||||
super(Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
static class SpecialResourcesProcessor implements ResourceProcessor<SpecialResources> {
|
||||
|
||||
boolean invoked = false;
|
||||
|
||||
@Override
|
||||
public SpecialResources process(SpecialResources resource) {
|
||||
this.invoked = true;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,6 @@ import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
import org.springframework.data.rest.webmvc.ResourceProcessorInvoker;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.AssociationOmittingSerializerModifier;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.AssociationUriResolvingDeserializerModifier;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.LookupObjectSerializer;
|
||||
@@ -49,6 +48,7 @@ import org.springframework.data.rest.webmvc.support.ExcerptProjector;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.ResourceProcessor;
|
||||
import org.springframework.hateoas.UriTemplate;
|
||||
import org.springframework.hateoas.mvc.ResourceProcessorInvoker;
|
||||
import org.springframework.plugin.core.OrderAwarePluginRegistry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
Reference in New Issue
Block a user