Fix for DATAREST-69. Now inject an EntityLinks into the controller and provide the RepositoryEntityLinks as a bean in the RepositoryRestMvcConfiguration.
This commit is contained in:
@@ -22,14 +22,11 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
*/
|
||||
public class RepositoryEntityLinks extends AbstractEntityLinks {
|
||||
|
||||
private final URI baseUri;
|
||||
private final Repositories repositories;
|
||||
private final RepositoryRestConfiguration config;
|
||||
|
||||
public RepositoryEntityLinks(URI baseUri,
|
||||
Repositories repositories,
|
||||
public RepositoryEntityLinks(Repositories repositories,
|
||||
RepositoryRestConfiguration config) {
|
||||
this.baseUri = baseUri;
|
||||
this.repositories = repositories;
|
||||
this.config = config;
|
||||
}
|
||||
@@ -48,7 +45,7 @@ public class RepositoryEntityLinks extends AbstractEntityLinks {
|
||||
if(null == persistentEntity) {
|
||||
throw new IllegalArgumentException(type + " is not managed by any repository.");
|
||||
}
|
||||
return new PersistentEntityLinkBuilder(baseUri, repoInfo, persistentEntity);
|
||||
return new PersistentEntityLinkBuilder(config.getBaseUri(), repoInfo, persistentEntity);
|
||||
}
|
||||
|
||||
@Override public LinkBuilder linkFor(Class<?> type, Object... parameters) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.data.rest.webmvc.support.ConstraintViolationException
|
||||
import org.springframework.data.rest.webmvc.support.ExceptionMessage;
|
||||
import org.springframework.data.rest.webmvc.support.JsonpResponse;
|
||||
import org.springframework.data.rest.webmvc.support.RepositoryConstraintViolationExceptionMessage;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.LinkBuilder;
|
||||
import org.springframework.hateoas.Resource;
|
||||
@@ -52,236 +53,239 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
*/
|
||||
public class AbstractRepositoryRestController implements ApplicationContextAware {
|
||||
|
||||
static final Resource<?> EMPTY_RESOURCE = new Resource<Object>(Collections.emptyList());
|
||||
static final Resources<Resource<?>> EMPTY_RESOURCES = new Resources<Resource<?>>(Collections.<Resource<?>>emptyList());
|
||||
static final Iterable<Resource<?>> EMPTY_RESOURCE_LIST = Collections.emptyList();
|
||||
static final TypeDescriptor STRING_TYPE = TypeDescriptor.valueOf(String.class);
|
||||
protected final Logger LOG = LoggerFactory.getLogger(getClass());
|
||||
protected final Repositories repositories;
|
||||
protected final RepositoryRestConfiguration config;
|
||||
protected final DomainClassConverter domainClassConverter;
|
||||
protected final ConversionService conversionService;
|
||||
protected final MethodParameterConversionService methodParameterConversionService;
|
||||
protected ApplicationContext applicationContext;
|
||||
static final Resource<?> EMPTY_RESOURCE = new Resource<Object>(Collections.emptyList());
|
||||
static final Resources<Resource<?>> EMPTY_RESOURCES = new Resources<Resource<?>>(Collections.<Resource<?>>emptyList());
|
||||
static final Iterable<Resource<?>> EMPTY_RESOURCE_LIST = Collections.emptyList();
|
||||
static final TypeDescriptor STRING_TYPE = TypeDescriptor.valueOf(String.class);
|
||||
protected final Logger LOG = LoggerFactory.getLogger(getClass());
|
||||
protected final Repositories repositories;
|
||||
protected final RepositoryRestConfiguration config;
|
||||
protected final DomainClassConverter domainClassConverter;
|
||||
protected final ConversionService conversionService;
|
||||
protected final MethodParameterConversionService methodParameterConversionService;
|
||||
protected final EntityLinks entityLinks;
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
public AbstractRepositoryRestController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService) {
|
||||
this.repositories = repositories;
|
||||
this.config = config;
|
||||
this.domainClassConverter = domainClassConverter;
|
||||
this.conversionService = conversionService;
|
||||
this.methodParameterConversionService = new MethodParameterConversionService(conversionService);
|
||||
}
|
||||
@Autowired
|
||||
public AbstractRepositoryRestController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService,
|
||||
EntityLinks entityLinks) {
|
||||
this.repositories = repositories;
|
||||
this.config = config;
|
||||
this.domainClassConverter = domainClassConverter;
|
||||
this.conversionService = conversionService;
|
||||
this.entityLinks = entityLinks;
|
||||
this.methodParameterConversionService = new MethodParameterConversionService(conversionService);
|
||||
}
|
||||
|
||||
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
NullPointerException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> handleNPE(NullPointerException npe) {
|
||||
return errorResponse(npe, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
@ExceptionHandler({
|
||||
NullPointerException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> handleNPE(NullPointerException npe) {
|
||||
return errorResponse(npe, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
ResourceNotFoundException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> handleNotFound() {
|
||||
return notFound();
|
||||
}
|
||||
@ExceptionHandler({
|
||||
ResourceNotFoundException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> handleNotFound() {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
NoSuchMethodError.class,
|
||||
HttpRequestMethodNotSupportedException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> handleNoSuchMethod() {
|
||||
return errorResponse(null, HttpStatus.METHOD_NOT_ALLOWED);
|
||||
}
|
||||
@ExceptionHandler({
|
||||
NoSuchMethodError.class,
|
||||
HttpRequestMethodNotSupportedException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> handleNoSuchMethod() {
|
||||
return errorResponse(null, HttpStatus.METHOD_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
HttpMessageNotReadableException.class,
|
||||
HttpMessageNotWritableException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<ExceptionMessage> handleNotReadable(HttpMessageNotReadableException e) {
|
||||
return badRequest(e);
|
||||
}
|
||||
@ExceptionHandler({
|
||||
HttpMessageNotReadableException.class,
|
||||
HttpMessageNotWritableException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<ExceptionMessage> handleNotReadable(HttpMessageNotReadableException e) {
|
||||
return badRequest(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle failures commonly thrown from code tries to read incoming data and convert or cast it to the right type.
|
||||
*
|
||||
* @param t
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
@ExceptionHandler({
|
||||
InvocationTargetException.class,
|
||||
IllegalArgumentException.class,
|
||||
ClassCastException.class,
|
||||
ConversionFailedException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<ExceptionMessage> handleMiscFailures(Throwable t) {
|
||||
return badRequest(t);
|
||||
}
|
||||
/**
|
||||
* Handle failures commonly thrown from code tries to read incoming data and convert or cast it to the right type.
|
||||
*
|
||||
* @param t
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
@ExceptionHandler({
|
||||
InvocationTargetException.class,
|
||||
IllegalArgumentException.class,
|
||||
ClassCastException.class,
|
||||
ConversionFailedException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity<ExceptionMessage> handleMiscFailures(Throwable t) {
|
||||
return badRequest(t);
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
ConstraintViolationException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity handleConstraintViolationException(ConstraintViolationException cve) {
|
||||
return response(null,
|
||||
new ConstraintViolationExceptionMessage(cve, applicationContext),
|
||||
HttpStatus.CONFLICT);
|
||||
}
|
||||
@ExceptionHandler({
|
||||
ConstraintViolationException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity handleConstraintViolationException(ConstraintViolationException cve) {
|
||||
return response(null,
|
||||
new ConstraintViolationExceptionMessage(cve, applicationContext),
|
||||
HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
RepositoryConstraintViolationException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity handleRepositoryConstraintViolationException(RepositoryConstraintViolationException rcve) {
|
||||
return response(null,
|
||||
new RepositoryConstraintViolationExceptionMessage(rcve, applicationContext),
|
||||
HttpStatus.CONFLICT);
|
||||
}
|
||||
@ExceptionHandler({
|
||||
RepositoryConstraintViolationException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity handleRepositoryConstraintViolationException(RepositoryConstraintViolationException rcve) {
|
||||
return response(null,
|
||||
new RepositoryConstraintViolationExceptionMessage(rcve, applicationContext),
|
||||
HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a 409 Conflict in case of concurrent modification.
|
||||
*
|
||||
* @param ex
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@ExceptionHandler({
|
||||
OptimisticLockingFailureException.class,
|
||||
DataIntegrityViolationException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity handleConflict(Exception ex) {
|
||||
return errorResponse(null, ex, HttpStatus.CONFLICT);
|
||||
}
|
||||
/**
|
||||
* Send a 409 Conflict in case of concurrent modification.
|
||||
*
|
||||
* @param ex
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@ExceptionHandler({
|
||||
OptimisticLockingFailureException.class,
|
||||
DataIntegrityViolationException.class
|
||||
})
|
||||
@ResponseBody
|
||||
public ResponseEntity handleConflict(Exception ex) {
|
||||
return errorResponse(null, ex, HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
protected <T> ResponseEntity<T> notFound() {
|
||||
return notFound(null, null);
|
||||
}
|
||||
protected <T> ResponseEntity<T> notFound() {
|
||||
return notFound(null, null);
|
||||
}
|
||||
|
||||
protected <T> ResponseEntity<T> notFound(HttpHeaders headers, T body) {
|
||||
return response(headers, body, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
protected <T> ResponseEntity<T> notFound(HttpHeaders headers, T body) {
|
||||
return response(headers, body, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
protected <T extends Throwable> ResponseEntity<ExceptionMessage> badRequest(T throwable) {
|
||||
return badRequest(null, throwable);
|
||||
}
|
||||
protected <T extends Throwable> ResponseEntity<ExceptionMessage> badRequest(T throwable) {
|
||||
return badRequest(null, throwable);
|
||||
}
|
||||
|
||||
protected <T extends Throwable> ResponseEntity<ExceptionMessage> badRequest(HttpHeaders headers, T throwable) {
|
||||
return errorResponse(headers, throwable, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
protected <T extends Throwable> ResponseEntity<ExceptionMessage> badRequest(HttpHeaders headers, T throwable) {
|
||||
return errorResponse(headers, throwable, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> internalServerError(T throwable) {
|
||||
return internalServerError(null, throwable);
|
||||
}
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> internalServerError(T throwable) {
|
||||
return internalServerError(null, throwable);
|
||||
}
|
||||
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> internalServerError(HttpHeaders headers, T throwable) {
|
||||
return errorResponse(headers, throwable, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> internalServerError(HttpHeaders headers, T throwable) {
|
||||
return errorResponse(headers, throwable, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> errorResponse(T throwable,
|
||||
HttpStatus status) {
|
||||
return errorResponse(null, throwable, status);
|
||||
}
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> errorResponse(T throwable,
|
||||
HttpStatus status) {
|
||||
return errorResponse(null, throwable, status);
|
||||
}
|
||||
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> errorResponse(HttpHeaders headers,
|
||||
T throwable,
|
||||
HttpStatus status) {
|
||||
LOG.error(throwable.getMessage(), throwable);
|
||||
return response(headers, new ExceptionMessage(throwable), status);
|
||||
}
|
||||
public <T extends Throwable> ResponseEntity<ExceptionMessage> errorResponse(HttpHeaders headers,
|
||||
T throwable,
|
||||
HttpStatus status) {
|
||||
LOG.error(throwable.getMessage(), throwable);
|
||||
return response(headers, new ExceptionMessage(throwable), status);
|
||||
}
|
||||
|
||||
public <T> ResponseEntity<T> response(HttpHeaders headers, T body, HttpStatus status) {
|
||||
HttpHeaders hdrs = new HttpHeaders();
|
||||
if(null != headers) {
|
||||
hdrs.putAll(headers);
|
||||
}
|
||||
return new ResponseEntity<T>(body, hdrs, status);
|
||||
}
|
||||
public <T> ResponseEntity<T> response(HttpHeaders headers, T body, HttpStatus status) {
|
||||
HttpHeaders hdrs = new HttpHeaders();
|
||||
if(null != headers) {
|
||||
hdrs.putAll(headers);
|
||||
}
|
||||
return new ResponseEntity<T>(body, hdrs, status);
|
||||
}
|
||||
|
||||
public <R extends Resource<?>> ResponseEntity<Resource<?>> resourceResponse(HttpHeaders headers,
|
||||
R resource,
|
||||
HttpStatus status) {
|
||||
HttpHeaders hdrs = new HttpHeaders();
|
||||
if(null != headers) {
|
||||
hdrs.putAll(headers);
|
||||
}
|
||||
return new ResponseEntity<Resource<?>>(resource, hdrs, status);
|
||||
}
|
||||
public <R extends Resource<?>> ResponseEntity<Resource<?>> resourceResponse(HttpHeaders headers,
|
||||
R resource,
|
||||
HttpStatus status) {
|
||||
HttpHeaders hdrs = new HttpHeaders();
|
||||
if(null != headers) {
|
||||
hdrs.putAll(headers);
|
||||
}
|
||||
return new ResponseEntity<Resource<?>>(resource, hdrs, status);
|
||||
}
|
||||
|
||||
protected <T> JsonpResponse<T> jsonpWrapResponse(RepositoryRestRequest repoRequest,
|
||||
T response,
|
||||
HttpStatus status) {
|
||||
return jsonpWrapResponse(repoRequest, response, null, status);
|
||||
}
|
||||
protected <T> JsonpResponse<T> jsonpWrapResponse(RepositoryRestRequest repoRequest,
|
||||
T response,
|
||||
HttpStatus status) {
|
||||
return jsonpWrapResponse(repoRequest, response, null, status);
|
||||
}
|
||||
|
||||
protected <T> JsonpResponse<T> jsonpWrapResponse(RepositoryRestRequest repoRequest,
|
||||
ResponseEntity<T> response) {
|
||||
return jsonpWrapResponse(repoRequest,
|
||||
response.getBody(),
|
||||
response.getHeaders(),
|
||||
response.getStatusCode());
|
||||
}
|
||||
protected <T> JsonpResponse<T> jsonpWrapResponse(RepositoryRestRequest repoRequest,
|
||||
ResponseEntity<T> response) {
|
||||
return jsonpWrapResponse(repoRequest,
|
||||
response.getBody(),
|
||||
response.getHeaders(),
|
||||
response.getStatusCode());
|
||||
}
|
||||
|
||||
protected <T> JsonpResponse<T> jsonpWrapResponse(RepositoryRestRequest repoRequest,
|
||||
T response,
|
||||
HttpHeaders headers,
|
||||
HttpStatus status) {
|
||||
String callback = repoRequest.getRequest().getParameter(config.getJsonpParamName());
|
||||
String errback = (null != config.getJsonpOnErrParamName()
|
||||
? repoRequest.getRequest().getParameter(config.getJsonpOnErrParamName())
|
||||
: null);
|
||||
ResponseEntity<T> newResponse;
|
||||
if(null != headers) {
|
||||
newResponse = new ResponseEntity<T>(response, headers, status);
|
||||
} else {
|
||||
newResponse = new ResponseEntity<T>(response, status);
|
||||
}
|
||||
return new JsonpResponse<T>(newResponse,
|
||||
(null != callback ? callback : config.getJsonpParamName()),
|
||||
(null != errback ? errback : config.getJsonpOnErrParamName()));
|
||||
}
|
||||
protected <T> JsonpResponse<T> jsonpWrapResponse(RepositoryRestRequest repoRequest,
|
||||
T response,
|
||||
HttpHeaders headers,
|
||||
HttpStatus status) {
|
||||
String callback = repoRequest.getRequest().getParameter(config.getJsonpParamName());
|
||||
String errback = (null != config.getJsonpOnErrParamName()
|
||||
? repoRequest.getRequest().getParameter(config.getJsonpOnErrParamName())
|
||||
: null);
|
||||
ResponseEntity<T> newResponse;
|
||||
if(null != headers) {
|
||||
newResponse = new ResponseEntity<T>(response, headers, status);
|
||||
} else {
|
||||
newResponse = new ResponseEntity<T>(response, status);
|
||||
}
|
||||
return new JsonpResponse<T>(newResponse,
|
||||
(null != callback ? callback : config.getJsonpParamName()),
|
||||
(null != errback ? errback : config.getJsonpOnErrParamName()));
|
||||
}
|
||||
|
||||
protected List<Link> queryMethodLinks(URI baseUri, Class<?> domainType) {
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(domainType);
|
||||
ResourceMapping repoMapping = ResourceMappingUtils.merge(
|
||||
repoInfo.getRepositoryInterface(),
|
||||
config.getResourceMappingForRepository(repoInfo.getRepositoryInterface())
|
||||
);
|
||||
for(Method method : repoInfo.getQueryMethods()) {
|
||||
LinkBuilder linkBuilder = BaseUriLinkBuilder.create(buildUri(baseUri, repoMapping.getPath(), "search"));
|
||||
ResourceMapping methodMapping = ResourceMappingUtils.merge(method,
|
||||
repoMapping.getResourceMappingFor(method.getName()));
|
||||
links.add(linkBuilder.slash(methodMapping.getPath())
|
||||
.withRel(repoMapping.getRel() + "." + methodMapping.getRel()));
|
||||
}
|
||||
return links;
|
||||
}
|
||||
protected List<Link> queryMethodLinks(URI baseUri, Class<?> domainType) {
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
RepositoryInformation repoInfo = repositories.getRepositoryInformationFor(domainType);
|
||||
ResourceMapping repoMapping = ResourceMappingUtils.merge(
|
||||
repoInfo.getRepositoryInterface(),
|
||||
config.getResourceMappingForRepository(repoInfo.getRepositoryInterface())
|
||||
);
|
||||
for(Method method : repoInfo.getQueryMethods()) {
|
||||
LinkBuilder linkBuilder = BaseUriLinkBuilder.create(buildUri(baseUri, repoMapping.getPath(), "search"));
|
||||
ResourceMapping methodMapping = ResourceMappingUtils.merge(method,
|
||||
repoMapping.getResourceMappingFor(method.getName()));
|
||||
links.add(linkBuilder.slash(methodMapping.getPath())
|
||||
.withRel(repoMapping.getRel() + "." + methodMapping.getRel()));
|
||||
}
|
||||
return links;
|
||||
}
|
||||
|
||||
protected Link resourceLink(RepositoryRestRequest repoRequest, Resource resource) {
|
||||
ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping();
|
||||
ResourceMapping entityMapping = repoRequest.getPersistentEntityResourceMapping();
|
||||
protected Link resourceLink(RepositoryRestRequest repoRequest, Resource resource) {
|
||||
ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping();
|
||||
ResourceMapping entityMapping = repoRequest.getPersistentEntityResourceMapping();
|
||||
|
||||
Link selfLink = resource.getLink("self");
|
||||
String rel = repoMapping.getRel() + "." + entityMapping.getRel();
|
||||
return new Link(selfLink.getHref(), rel);
|
||||
}
|
||||
Link selfLink = resource.getLink("self");
|
||||
String rel = repoMapping.getRel() + "." + entityMapping.getRel();
|
||||
return new Link(selfLink.getHref(), rel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ package org.springframework.data.rest.webmvc;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.repository.support.DomainClassConverter;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.repository.support.RepositoryEntityLinks;
|
||||
import org.springframework.data.rest.webmvc.support.JsonpResponse;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.Resource;
|
||||
@@ -23,43 +23,46 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@RequestMapping("/")
|
||||
public class RepositoryController extends AbstractRepositoryRestController {
|
||||
|
||||
public RepositoryController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService) {
|
||||
super(repositories, config, domainClassConverter, conversionService);
|
||||
}
|
||||
@Autowired
|
||||
public RepositoryController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService,
|
||||
EntityLinks entityLinks) {
|
||||
super(repositories,
|
||||
config,
|
||||
domainClassConverter,
|
||||
conversionService,
|
||||
entityLinks);
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-compact+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> listRepositories(RepositoryRestRequest repoRequest)
|
||||
throws ResourceNotFoundException {
|
||||
EntityLinks linkBuilder = new RepositoryEntityLinks(repoRequest.getBaseUri(),
|
||||
repositories,
|
||||
config);
|
||||
Resource<?> links = new Resource<Object>(emptyList());
|
||||
for(Class<?> domainType : repositories) {
|
||||
links.add(linkBuilder.linkToCollectionResource(domainType));
|
||||
}
|
||||
return links;
|
||||
}
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-compact+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> listRepositories()
|
||||
throws ResourceNotFoundException {
|
||||
Resource<?> links = new Resource<Object>(emptyList());
|
||||
for(Class<?> domainType : repositories) {
|
||||
links.add(entityLinks.linkToCollectionResource(domainType));
|
||||
}
|
||||
return links;
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<? extends Resource<?>> jsonpListRepositories(RepositoryRestRequest repoRequest)
|
||||
throws ResourceNotFoundException {
|
||||
return jsonpWrapResponse(repoRequest, listRepositories(repoRequest), HttpStatus.OK);
|
||||
}
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<? extends Resource<?>> jsonpListRepositories(RepositoryRestRequest repoRequest)
|
||||
throws ResourceNotFoundException {
|
||||
return jsonpWrapResponse(repoRequest, listRepositories(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.rest.repository.json.JsonSchema;
|
||||
import org.springframework.data.rest.repository.json.PersistentEntityToJsonSchemaConverter;
|
||||
import org.springframework.data.rest.repository.support.DomainObjectMerger;
|
||||
import org.springframework.data.rest.webmvc.support.JsonpResponse;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.Resources;
|
||||
@@ -54,8 +55,13 @@ public class RepositoryEntityController extends AbstractRepositoryRestController
|
||||
public RepositoryEntityController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService) {
|
||||
super(repositories, config, domainClassConverter, conversionService);
|
||||
ConversionService conversionService,
|
||||
EntityLinks entityLinks) {
|
||||
super(repositories,
|
||||
config,
|
||||
domainClassConverter,
|
||||
conversionService,
|
||||
entityLinks);
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.rest.repository.support.RepositoryEntityLinks;
|
||||
import org.springframework.data.rest.repository.support.RepositoryInformationSupport;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
public class RepositoryEntityLinksMethodArgumentResolver
|
||||
extends RepositoryInformationSupport
|
||||
implements HandlerMethodArgumentResolver {
|
||||
|
||||
@Autowired
|
||||
private BaseUriMethodArgumentResolver baseUriResolver;
|
||||
|
||||
@Override public boolean supportsParameter(MethodParameter parameter) {
|
||||
return EntityLinks.class.isAssignableFrom(parameter.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory)
|
||||
throws Exception {
|
||||
URI baseUri = (URI)baseUriResolver.resolveArgument(parameter,
|
||||
mavContainer,
|
||||
webRequest,
|
||||
binderFactory);
|
||||
return new RepositoryEntityLinks(baseUri, repositories, config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import org.springframework.data.rest.repository.context.BeforeLinkDeleteEvent;
|
||||
import org.springframework.data.rest.repository.context.BeforeLinkSaveEvent;
|
||||
import org.springframework.data.rest.repository.invoke.RepositoryMethodInvoker;
|
||||
import org.springframework.data.rest.webmvc.support.JsonpResponse;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -47,485 +48,490 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@RequestMapping("/{repository}/{id}/{property}")
|
||||
public class RepositoryPropertyReferenceController extends AbstractRepositoryRestController {
|
||||
|
||||
public RepositoryPropertyReferenceController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService) {
|
||||
super(repositories, config, domainClassConverter, conversionService);
|
||||
}
|
||||
public RepositoryPropertyReferenceController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService,
|
||||
EntityLinks entityLinks) {
|
||||
super(repositories,
|
||||
config,
|
||||
domainClassConverter,
|
||||
conversionService,
|
||||
entityLinks);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-verbose+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> followPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(prop.property.isCollectionLike()) {
|
||||
List<Resource<?>> resources = new ArrayList<Resource<?>>();
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Object obj : ((Iterable)prop.propertyValue)) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity, obj, repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(obj, conversionService);
|
||||
per.add(selfLink);
|
||||
resources.add(per);
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-verbose+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> followPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(prop.property.isCollectionLike()) {
|
||||
List<Resource<?>> resources = new ArrayList<Resource<?>>();
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Object obj : ((Iterable)prop.propertyValue)) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity, obj, repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(obj, conversionService);
|
||||
per.add(selfLink);
|
||||
resources.add(per);
|
||||
}
|
||||
|
||||
return new Resource<Object>(resources);
|
||||
} else if(prop.property.isMap()) {
|
||||
Map<Object, Resource<?>> resources = new HashMap<Object, Resource<?>>();
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Map.Entry<Object, Object> entry : ((Map<Object, Object>)prop.propertyValue).entrySet()) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity,
|
||||
entry.getValue(),
|
||||
repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(entry.getValue(), conversionService);
|
||||
per.add(selfLink);
|
||||
resources.put(entry.getKey(), per);
|
||||
}
|
||||
return new Resource<Object>(resources);
|
||||
} else if(prop.property.isMap()) {
|
||||
Map<Object, Resource<?>> resources = new HashMap<Object, Resource<?>>();
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Map.Entry<Object, Object> entry : ((Map<Object, Object>)prop.propertyValue).entrySet()) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity,
|
||||
entry.getValue(),
|
||||
repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(entry.getValue(), conversionService);
|
||||
per.add(selfLink);
|
||||
resources.put(entry.getKey(), per);
|
||||
}
|
||||
|
||||
return new Resource<Object>(resources);
|
||||
} else {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(repositories.getPersistentEntity(prop.propertyType),
|
||||
prop.propertyValue,
|
||||
repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(prop.propertyValue, conversionService);
|
||||
per.add(selfLink);
|
||||
return new Resource<Object>(resources);
|
||||
} else {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(repositories.getPersistentEntity(prop.propertyType),
|
||||
prop.propertyValue,
|
||||
repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(prop.propertyValue, conversionService);
|
||||
per.add(selfLink);
|
||||
|
||||
headers.set("Content-Location", selfLink.getHref());
|
||||
headers.set("Content-Location", selfLink.getHref());
|
||||
|
||||
return new Resource<Object>(per);
|
||||
}
|
||||
}
|
||||
};
|
||||
Resource<?> responseResource = doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
return resourceResponse(headers, responseResource, HttpStatus.OK);
|
||||
}
|
||||
return new Resource<Object>(per);
|
||||
}
|
||||
}
|
||||
};
|
||||
Resource<?> responseResource = doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
return resourceResponse(headers, responseResource, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-verbose+json",
|
||||
"application/x-spring-data-compact+json",
|
||||
"text/uri-list"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> followPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
final @PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(prop.property.isCollectionLike()) {
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Object obj : ((Iterable)prop.propertyValue)) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(obj, conversionService);
|
||||
String sId = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
if(propertyId.equals(sId)) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity, obj, repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(obj, conversionService);
|
||||
per.add(selfLink);
|
||||
headers.set("Content-Location", selfLink.getHref());
|
||||
return per;
|
||||
}
|
||||
}
|
||||
} else if(prop.property.isMap()) {
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Map.Entry<Object, Object> entry : ((Map<Object, Object>)prop.propertyValue).entrySet()) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(entry.getValue(), conversionService);
|
||||
String sId = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
if(propertyId.equals(sId)) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity,
|
||||
entry.getValue(),
|
||||
repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(entry.getValue(), conversionService);
|
||||
per.add(selfLink);
|
||||
headers.set("Content-Location", selfLink.getHref());
|
||||
return per;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return new Resource<Object>(prop.propertyValue);
|
||||
}
|
||||
throw new IllegalArgumentException(new ResourceNotFoundException());
|
||||
}
|
||||
};
|
||||
Resource<?> responseResource = doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
return resourceResponse(headers, responseResource, HttpStatus.OK);
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-verbose+json",
|
||||
"application/x-spring-data-compact+json",
|
||||
"text/uri-list"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> followPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
final @PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(prop.property.isCollectionLike()) {
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Object obj : ((Iterable)prop.propertyValue)) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(obj, conversionService);
|
||||
String sId = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
if(propertyId.equals(sId)) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity, obj, repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(obj, conversionService);
|
||||
per.add(selfLink);
|
||||
headers.set("Content-Location", selfLink.getHref());
|
||||
return per;
|
||||
}
|
||||
}
|
||||
} else if(prop.property.isMap()) {
|
||||
PersistentEntity entity = repositories.getPersistentEntity(prop.propertyType);
|
||||
for(Map.Entry<Object, Object> entry : ((Map<Object, Object>)prop.propertyValue).entrySet()) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(entry.getValue(), conversionService);
|
||||
String sId = propValWrapper.getProperty(prop.entity.getIdProperty()).toString();
|
||||
if(propertyId.equals(sId)) {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(entity,
|
||||
entry.getValue(),
|
||||
repoRequest.getBaseUri());
|
||||
Link selfLink = repoRequest.buildEntitySelfLink(entry.getValue(), conversionService);
|
||||
per.add(selfLink);
|
||||
headers.set("Content-Location", selfLink.getHref());
|
||||
return per;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return new Resource<Object>(prop.propertyValue);
|
||||
}
|
||||
throw new IllegalArgumentException(new ResourceNotFoundException());
|
||||
}
|
||||
};
|
||||
Resource<?> responseResource = doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
return resourceResponse(headers, responseResource, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/x-spring-data-compact+json",
|
||||
"text/uri-list"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> followPropertyReferenceCompact(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
ResponseEntity<Resource<?>> response = followPropertyReference(repoRequest, id, property);
|
||||
if(response.getStatusCode() != HttpStatus.OK) {
|
||||
return response;
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/x-spring-data-compact+json",
|
||||
"text/uri-list"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> followPropertyReferenceCompact(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
ResponseEntity<Resource<?>> response = followPropertyReference(repoRequest, id, property);
|
||||
if(response.getStatusCode() != HttpStatus.OK) {
|
||||
return response;
|
||||
}
|
||||
|
||||
ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping();
|
||||
ResourceMapping entityMapping = repoRequest.getPersistentEntityResourceMapping();
|
||||
String propName = entityMapping.getNameForPath(property);
|
||||
ResourceMapping propMapping = entityMapping.getResourceMappingFor(entityMapping.getNameForPath(property));
|
||||
PersistentProperty persistentProp = repoRequest.getPersistentEntity().getPersistentProperty(propName);
|
||||
Class<?> propType = (persistentProp.isCollectionLike() || persistentProp.isMap()
|
||||
? persistentProp.getComponentType()
|
||||
: persistentProp.getType());
|
||||
ResourceMapping propRepoMapping = getResourceMapping(config, repositories.getRepositoryInformationFor(propType));
|
||||
String propRel = String.format("%s.%s.%s.%s",
|
||||
repoMapping.getRel(),
|
||||
entityMapping.getRel(),
|
||||
(null != propMapping ? propMapping.getRel() : property),
|
||||
propRepoMapping.getRel());
|
||||
ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping();
|
||||
ResourceMapping entityMapping = repoRequest.getPersistentEntityResourceMapping();
|
||||
String propName = entityMapping.getNameForPath(property);
|
||||
ResourceMapping propMapping = entityMapping.getResourceMappingFor(entityMapping.getNameForPath(property));
|
||||
PersistentProperty persistentProp = repoRequest.getPersistentEntity().getPersistentProperty(propName);
|
||||
Class<?> propType = (persistentProp.isCollectionLike() || persistentProp.isMap()
|
||||
? persistentProp.getComponentType()
|
||||
: persistentProp.getType());
|
||||
ResourceMapping propRepoMapping = getResourceMapping(config, repositories.getRepositoryInformationFor(propType));
|
||||
String propRel = String.format("%s.%s.%s.%s",
|
||||
repoMapping.getRel(),
|
||||
entityMapping.getRel(),
|
||||
(null != propMapping ? propMapping.getRel() : property),
|
||||
propRepoMapping.getRel());
|
||||
|
||||
Resource<?> resource = response.getBody();
|
||||
Resource<?> resource = response.getBody();
|
||||
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
|
||||
URI entityBaseUri = buildUri(repoRequest.getBaseUri(),
|
||||
repoMapping.getPath(),
|
||||
id,
|
||||
property);
|
||||
URI entityBaseUri = buildUri(repoRequest.getBaseUri(),
|
||||
repoMapping.getPath(),
|
||||
id,
|
||||
property);
|
||||
|
||||
if(resource.getContent() instanceof Iterable) {
|
||||
for(Resource<?> res : (Iterable<Resource<?>>)resource.getContent()) {
|
||||
Link propLink = propertyReferenceLink(res, entityBaseUri, propRel);
|
||||
links.add(propLink);
|
||||
}
|
||||
} else if(resource.getContent() instanceof Map) {
|
||||
for(Map.Entry<Object, Resource<?>> entry : ((Map<Object, Resource<?>>)resource.getContent()).entrySet()) {
|
||||
Link l = new Link(entry.getValue().getLink("self").getHref(), conversionService.convert(entry.getKey(),
|
||||
String.class));
|
||||
links.add(l);
|
||||
}
|
||||
} else {
|
||||
links.add(new Link(entityBaseUri.toString(), propRel));
|
||||
}
|
||||
if(resource.getContent() instanceof Iterable) {
|
||||
for(Resource<?> res : (Iterable<Resource<?>>)resource.getContent()) {
|
||||
Link propLink = propertyReferenceLink(res, entityBaseUri, propRel);
|
||||
links.add(propLink);
|
||||
}
|
||||
} else if(resource.getContent() instanceof Map) {
|
||||
for(Map.Entry<Object, Resource<?>> entry : ((Map<Object, Resource<?>>)resource.getContent()).entrySet()) {
|
||||
Link l = new Link(entry.getValue().getLink("self").getHref(), conversionService.convert(entry.getKey(),
|
||||
String.class));
|
||||
links.add(l);
|
||||
}
|
||||
} else {
|
||||
links.add(new Link(entityBaseUri.toString(), propRel));
|
||||
}
|
||||
|
||||
return resourceResponse(null, new Resource<Object>(EMPTY_RESOURCE_LIST, links), HttpStatus.OK);
|
||||
}
|
||||
return resourceResponse(null, new Resource<Object>(EMPTY_RESOURCE_LIST, links), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpFollowPropertyReference(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest,
|
||||
followPropertyReference(repoRequest,
|
||||
id,
|
||||
property),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpFollowPropertyReference(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest,
|
||||
followPropertyReference(repoRequest,
|
||||
id,
|
||||
property),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpFollowPropertyReference(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
@PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest,
|
||||
followPropertyReference(repoRequest,
|
||||
id,
|
||||
property,
|
||||
propertyId),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpFollowPropertyReference(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
@PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest,
|
||||
followPropertyReference(repoRequest,
|
||||
id,
|
||||
property,
|
||||
propertyId),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = {
|
||||
RequestMethod.POST,
|
||||
RequestMethod.PUT
|
||||
},
|
||||
consumes = {
|
||||
"application/json",
|
||||
"application/x-spring-data-compact+json",
|
||||
"text/uri-list"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> createPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
final @RequestBody Resource<Object> incoming,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(!repoMethodInvoker.hasSaveOne()) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(prop.property.isCollectionLike()) {
|
||||
Collection coll = new ArrayList();
|
||||
if("POST".equals(repoRequest.getRequest().getMethod())) {
|
||||
coll.addAll((Collection)prop.propertyValue);
|
||||
}
|
||||
for(Link l : incoming.getLinks()) {
|
||||
Object propVal = loadPropertyValue(prop.propertyType, l.getHref());
|
||||
coll.add(propVal);
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, coll);
|
||||
} else if(prop.property.isMap()) {
|
||||
Map m = new HashMap();
|
||||
if("POST".equals(repoRequest.getRequest().getMethod())) {
|
||||
m.putAll((Map)prop.propertyValue);
|
||||
}
|
||||
for(Link l : incoming.getLinks()) {
|
||||
Object propVal = loadPropertyValue(prop.propertyType, l.getHref());
|
||||
m.put(l.getRel(), propVal);
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, m);
|
||||
} else {
|
||||
if("POST".equals(repoRequest.getRequest().getMethod())) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot POST a reference to this singular property since the property type is not a List or a Map.");
|
||||
}
|
||||
if(incoming.getLinks().size() != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must send only 1 link to update a property reference that isn't a List or a Map.");
|
||||
}
|
||||
Object propVal = loadPropertyValue(prop.propertyType, incoming.getLinks().get(0).getHref());
|
||||
prop.wrapper.setProperty(prop.property, propVal);
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = {
|
||||
RequestMethod.POST,
|
||||
RequestMethod.PUT
|
||||
},
|
||||
consumes = {
|
||||
"application/json",
|
||||
"application/x-spring-data-compact+json",
|
||||
"text/uri-list"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> createPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
final @RequestBody Resource<Object> incoming,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(!repoMethodInvoker.hasSaveOne()) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(prop.property.isCollectionLike()) {
|
||||
Collection coll = new ArrayList();
|
||||
if("POST".equals(repoRequest.getRequest().getMethod())) {
|
||||
coll.addAll((Collection)prop.propertyValue);
|
||||
}
|
||||
for(Link l : incoming.getLinks()) {
|
||||
Object propVal = loadPropertyValue(prop.propertyType, l.getHref());
|
||||
coll.add(propVal);
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, coll);
|
||||
} else if(prop.property.isMap()) {
|
||||
Map m = new HashMap();
|
||||
if("POST".equals(repoRequest.getRequest().getMethod())) {
|
||||
m.putAll((Map)prop.propertyValue);
|
||||
}
|
||||
for(Link l : incoming.getLinks()) {
|
||||
Object propVal = loadPropertyValue(prop.propertyType, l.getHref());
|
||||
m.put(l.getRel(), propVal);
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, m);
|
||||
} else {
|
||||
if("POST".equals(repoRequest.getRequest().getMethod())) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot POST a reference to this singular property since the property type is not a List or a Map.");
|
||||
}
|
||||
if(incoming.getLinks().size() != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must send only 1 link to update a property reference that isn't a List or a Map.");
|
||||
}
|
||||
Object propVal = loadPropertyValue(prop.propertyType, incoming.getLinks().get(0).getHref());
|
||||
prop.wrapper.setProperty(prop.property, propVal);
|
||||
}
|
||||
|
||||
applicationContext.publishEvent(new BeforeLinkSaveEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = repoMethodInvoker.save(prop.wrapper.getBean());
|
||||
applicationContext.publishEvent(new AfterLinkSaveEvent(result, prop.propertyValue));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
return resourceResponse(null, EMPTY_RESOURCE, HttpStatus.CREATED);
|
||||
}
|
||||
applicationContext.publishEvent(new BeforeLinkSaveEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = repoMethodInvoker.save(prop.wrapper.getBean());
|
||||
applicationContext.publishEvent(new AfterLinkSaveEvent(result, prop.propertyValue));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
return resourceResponse(null, EMPTY_RESOURCE, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = {
|
||||
RequestMethod.POST,
|
||||
RequestMethod.PUT
|
||||
},
|
||||
consumes = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpCreatePropertyReference(final RepositoryRestRequest repoRequest,
|
||||
final @RequestBody Resource<Object> incoming,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest, createPropertyReference(repoRequest,
|
||||
incoming,
|
||||
id,
|
||||
property));
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
method = {
|
||||
RequestMethod.POST,
|
||||
RequestMethod.PUT
|
||||
},
|
||||
consumes = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpCreatePropertyReference(final RepositoryRestRequest repoRequest,
|
||||
final @RequestBody Resource<Object> incoming,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest, createPropertyReference(repoRequest,
|
||||
incoming,
|
||||
id,
|
||||
property));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.DELETE
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> deletePropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
final @PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(!repoMethodInvoker.hasDeleteOne()) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.DELETE
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Resource<?>> deletePropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
final @PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
final RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(!repoMethodInvoker.hasDeleteOne()) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(null == prop.propertyValue) {
|
||||
return null;
|
||||
}
|
||||
if(prop.property.isCollectionLike()) {
|
||||
Collection coll = new ArrayList();
|
||||
for(Object obj : (Collection)prop.propertyValue) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(obj, conversionService);
|
||||
String s = (String)propValWrapper.getProperty(prop.entity.getIdProperty(), String.class, false);
|
||||
if(!propertyId.equals(s)) {
|
||||
coll.add(obj);
|
||||
}
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, coll);
|
||||
} else if(prop.property.isMap()) {
|
||||
Map m = new HashMap();
|
||||
for(Map.Entry<Object, Object> entry : ((Map<Object, Object>)prop.propertyValue).entrySet()) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(entry.getValue(), conversionService);
|
||||
String s = (String)propValWrapper.getProperty(prop.entity.getIdProperty(), String.class, false);
|
||||
if(!propertyId.equals(s)) {
|
||||
m.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, m);
|
||||
} else {
|
||||
prop.wrapper.setProperty(prop.property, null);
|
||||
}
|
||||
Function<ReferencedProperty, Resource<?>> handler = new Function<ReferencedProperty, Resource<?>>() {
|
||||
@Override public Resource<?> apply(ReferencedProperty prop) {
|
||||
if(null == prop.propertyValue) {
|
||||
return null;
|
||||
}
|
||||
if(prop.property.isCollectionLike()) {
|
||||
Collection coll = new ArrayList();
|
||||
for(Object obj : (Collection)prop.propertyValue) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(obj, conversionService);
|
||||
String s = (String)propValWrapper.getProperty(prop.entity.getIdProperty(), String.class, false);
|
||||
if(!propertyId.equals(s)) {
|
||||
coll.add(obj);
|
||||
}
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, coll);
|
||||
} else if(prop.property.isMap()) {
|
||||
Map m = new HashMap();
|
||||
for(Map.Entry<Object, Object> entry : ((Map<Object, Object>)prop.propertyValue).entrySet()) {
|
||||
BeanWrapper propValWrapper = BeanWrapper.create(entry.getValue(), conversionService);
|
||||
String s = (String)propValWrapper.getProperty(prop.entity.getIdProperty(), String.class, false);
|
||||
if(!propertyId.equals(s)) {
|
||||
m.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
prop.wrapper.setProperty(prop.property, m);
|
||||
} else {
|
||||
prop.wrapper.setProperty(prop.property, null);
|
||||
}
|
||||
|
||||
applicationContext.publishEvent(new BeforeLinkDeleteEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = repoMethodInvoker.save(prop.wrapper.getBean());
|
||||
applicationContext.publishEvent(new AfterLinkDeleteEvent(result, prop.propertyValue));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
applicationContext.publishEvent(new BeforeLinkDeleteEvent(prop.wrapper.getBean(), prop.propertyValue));
|
||||
Object result = repoMethodInvoker.save(prop.wrapper.getBean());
|
||||
applicationContext.publishEvent(new AfterLinkDeleteEvent(result, prop.propertyValue));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
doWithReferencedProperty(repoRequest,
|
||||
id,
|
||||
property,
|
||||
handler);
|
||||
|
||||
return resourceResponse(null, EMPTY_RESOURCE, HttpStatus.NO_CONTENT);
|
||||
}
|
||||
return resourceResponse(null, EMPTY_RESOURCE, HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.DELETE,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpDeletePropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
final @PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest, deletePropertyReference(repoRequest,
|
||||
id,
|
||||
property,
|
||||
propertyId));
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{propertyId}",
|
||||
method = RequestMethod.DELETE,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpDeletePropertyReference(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id,
|
||||
@PathVariable String property,
|
||||
final @PathVariable String propertyId)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
return jsonpWrapResponse(repoRequest, deletePropertyReference(repoRequest,
|
||||
id,
|
||||
property,
|
||||
propertyId));
|
||||
}
|
||||
|
||||
private Link propertyReferenceLink(Resource<?> resource,
|
||||
URI baseUri,
|
||||
String rel) {
|
||||
Link selfLink = resource.getLink("self");
|
||||
String objId = selfLink.getHref().substring(selfLink.getHref().lastIndexOf('/') + 1);
|
||||
return new Link(buildUri(baseUri, objId).toString(), rel);
|
||||
}
|
||||
private Link propertyReferenceLink(Resource<?> resource,
|
||||
URI baseUri,
|
||||
String rel) {
|
||||
Link selfLink = resource.getLink("self");
|
||||
String objId = selfLink.getHref().substring(selfLink.getHref().lastIndexOf('/') + 1);
|
||||
return new Link(buildUri(baseUri, objId).toString(), rel);
|
||||
}
|
||||
|
||||
private Object loadPropertyValue(Class<?> type, String href) {
|
||||
String id = href.substring(href.lastIndexOf('/') + 1);
|
||||
return domainClassConverter.convert(id,
|
||||
STRING_TYPE,
|
||||
TypeDescriptor.valueOf(type));
|
||||
}
|
||||
private Object loadPropertyValue(Class<?> type, String href) {
|
||||
String id = href.substring(href.lastIndexOf('/') + 1);
|
||||
return domainClassConverter.convert(id,
|
||||
STRING_TYPE,
|
||||
TypeDescriptor.valueOf(type));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private Resource<?> doWithReferencedProperty(RepositoryRestRequest repoRequest,
|
||||
String id,
|
||||
String propertyPath,
|
||||
Function<ReferencedProperty, Resource<?>> handler)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(!repoMethodInvoker.hasFindOne()) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private Resource<?> doWithReferencedProperty(RepositoryRestRequest repoRequest,
|
||||
String id,
|
||||
String propertyPath,
|
||||
Function<ReferencedProperty, Resource<?>> handler)
|
||||
throws ResourceNotFoundException, NoSuchMethodException {
|
||||
RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(!repoMethodInvoker.hasFindOne()) {
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
|
||||
Object domainObj = domainClassConverter.convert(id,
|
||||
STRING_TYPE,
|
||||
TypeDescriptor.valueOf(repoRequest.getPersistentEntity()
|
||||
.getType()));
|
||||
if(null == domainObj) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
Object domainObj = domainClassConverter.convert(id,
|
||||
STRING_TYPE,
|
||||
TypeDescriptor.valueOf(repoRequest.getPersistentEntity()
|
||||
.getType()));
|
||||
if(null == domainObj) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
String propertyName = repoRequest.getPersistentEntityResourceMapping().getNameForPath(propertyPath);
|
||||
PersistentProperty prop = repoRequest.getPersistentEntity().getPersistentProperty(propertyName);
|
||||
if(null == prop) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
String propertyName = repoRequest.getPersistentEntityResourceMapping().getNameForPath(propertyPath);
|
||||
PersistentProperty prop = repoRequest.getPersistentEntity().getPersistentProperty(propertyName);
|
||||
if(null == prop) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
BeanWrapper wrapper = BeanWrapper.create(domainObj, conversionService);
|
||||
Object propVal = wrapper.getProperty(prop);
|
||||
if(null == propVal) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
BeanWrapper wrapper = BeanWrapper.create(domainObj, conversionService);
|
||||
Object propVal = wrapper.getProperty(prop);
|
||||
if(null == propVal) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
return handler.apply(new ReferencedProperty(prop,
|
||||
propVal,
|
||||
wrapper));
|
||||
}
|
||||
return handler.apply(new ReferencedProperty(prop,
|
||||
propVal,
|
||||
wrapper));
|
||||
}
|
||||
|
||||
private class ReferencedProperty {
|
||||
final PersistentEntity entity;
|
||||
final PersistentProperty property;
|
||||
final Class<?> propertyType;
|
||||
final Object propertyValue;
|
||||
final BeanWrapper wrapper;
|
||||
final RepositoryInformation propertyRepoInfo;
|
||||
final Object propertyRepo;
|
||||
final RepositoryMethodInvoker repoMethodInvoker;
|
||||
private class ReferencedProperty {
|
||||
final PersistentEntity entity;
|
||||
final PersistentProperty property;
|
||||
final Class<?> propertyType;
|
||||
final Object propertyValue;
|
||||
final BeanWrapper wrapper;
|
||||
final RepositoryInformation propertyRepoInfo;
|
||||
final Object propertyRepo;
|
||||
final RepositoryMethodInvoker repoMethodInvoker;
|
||||
|
||||
private ReferencedProperty(PersistentProperty property,
|
||||
Object propertyValue,
|
||||
BeanWrapper wrapper) {
|
||||
this.property = property;
|
||||
this.propertyValue = propertyValue;
|
||||
this.wrapper = wrapper;
|
||||
if(property.isCollectionLike()) {
|
||||
this.propertyType = property.getComponentType();
|
||||
} else if(property.isMap()) {
|
||||
this.propertyType = property.getMapValueType();
|
||||
} else {
|
||||
this.propertyType = property.getType();
|
||||
}
|
||||
this.propertyRepoInfo = repositories.getRepositoryInformationFor(propertyType);
|
||||
this.entity = repositories.getPersistentEntity(propertyType);
|
||||
this.propertyRepo = repositories.getRepositoryFor(entity.getType());
|
||||
this.repoMethodInvoker = new RepositoryMethodInvoker(propertyRepo, propertyRepoInfo, entity);
|
||||
}
|
||||
}
|
||||
private ReferencedProperty(PersistentProperty property,
|
||||
Object propertyValue,
|
||||
BeanWrapper wrapper) {
|
||||
this.property = property;
|
||||
this.propertyValue = propertyValue;
|
||||
this.wrapper = wrapper;
|
||||
if(property.isCollectionLike()) {
|
||||
this.propertyType = property.getComponentType();
|
||||
} else if(property.isMap()) {
|
||||
this.propertyType = property.getMapValueType();
|
||||
} else {
|
||||
this.propertyType = property.getType();
|
||||
}
|
||||
this.propertyRepoInfo = repositories.getRepositoryInformationFor(propertyType);
|
||||
this.entity = repositories.getPersistentEntity(propertyType);
|
||||
this.propertyRepo = repositories.getRepositoryFor(entity.getType());
|
||||
this.repoMethodInvoker = new RepositoryMethodInvoker(propertyRepo, propertyRepoInfo, entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.data.rest.repository.PersistentEntityResource;
|
||||
import org.springframework.data.rest.repository.invoke.RepositoryMethod;
|
||||
import org.springframework.data.rest.repository.invoke.RepositoryMethodInvoker;
|
||||
import org.springframework.data.rest.webmvc.support.JsonpResponse;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -38,204 +39,209 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@RequestMapping("/{repository}/search")
|
||||
public class RepositorySearchController extends AbstractRepositoryRestController {
|
||||
|
||||
public RepositorySearchController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService) {
|
||||
super(repositories, config, domainClassConverter, conversionService);
|
||||
}
|
||||
public RepositorySearchController(Repositories repositories,
|
||||
RepositoryRestConfiguration config,
|
||||
DomainClassConverter domainClassConverter,
|
||||
ConversionService conversionService,
|
||||
EntityLinks entityLinks) {
|
||||
super(repositories,
|
||||
config,
|
||||
domainClassConverter,
|
||||
conversionService,
|
||||
entityLinks);
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-compact+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> list(RepositoryRestRequest repoRequest) {
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
links.addAll(queryMethodLinks(repoRequest.getBaseUri(),
|
||||
repoRequest.getPersistentEntity().getType()));
|
||||
return new Resource<Object>(Collections.emptyList(), links);
|
||||
}
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-compact+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> list(RepositoryRestRequest repoRequest) {
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
links.addAll(queryMethodLinks(repoRequest.getBaseUri(),
|
||||
repoRequest.getPersistentEntity().getType()));
|
||||
return new Resource<Object>(Collections.emptyList(), links);
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpList(RepositoryRestRequest repoRequest) {
|
||||
return jsonpWrapResponse(repoRequest, list(repoRequest), HttpStatus.OK);
|
||||
}
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<?> jsonpList(RepositoryRestRequest repoRequest) {
|
||||
return jsonpWrapResponse(repoRequest, list(repoRequest), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{method}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-verbose+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> query(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String method)
|
||||
throws ResourceNotFoundException {
|
||||
RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(repoMethodInvoker.getQueryMethods().isEmpty()) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@RequestMapping(
|
||||
value = "/{method}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/json",
|
||||
"application/x-spring-data-verbose+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> query(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String method)
|
||||
throws ResourceNotFoundException {
|
||||
RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(repoMethodInvoker.getQueryMethods().isEmpty()) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping();
|
||||
String methodName = repoMapping.getNameForPath(method);
|
||||
RepositoryMethod repoMethod = repoMethodInvoker.getQueryMethods().get(methodName);
|
||||
if(null == repoMethod) {
|
||||
for(RepositoryMethod queryMethod : repoMethodInvoker.getQueryMethods().values()) {
|
||||
String path = findPath(queryMethod.getMethod());
|
||||
if(path.equals(method)) {
|
||||
repoMethod = queryMethod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(null == repoMethod) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
}
|
||||
ResourceMapping repoMapping = repoRequest.getRepositoryResourceMapping();
|
||||
String methodName = repoMapping.getNameForPath(method);
|
||||
RepositoryMethod repoMethod = repoMethodInvoker.getQueryMethods().get(methodName);
|
||||
if(null == repoMethod) {
|
||||
for(RepositoryMethod queryMethod : repoMethodInvoker.getQueryMethods().values()) {
|
||||
String path = findPath(queryMethod.getMethod());
|
||||
if(path.equals(method)) {
|
||||
repoMethod = queryMethod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(null == repoMethod) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
List<MethodParameter> methodParams = repoMethod.getParameters();
|
||||
Object[] paramValues = new Object[methodParams.size()];
|
||||
if(!methodParams.isEmpty()) {
|
||||
for(int i = 0; i < paramValues.length; i++) {
|
||||
MethodParameter param = methodParams.get(i);
|
||||
if(Pageable.class.isAssignableFrom(param.getParameterType())) {
|
||||
paramValues[i] = new PageRequest(repoRequest.getPagingAndSorting().getPageNumber(),
|
||||
repoRequest.getPagingAndSorting().getPageSize(),
|
||||
repoRequest.getPagingAndSorting().getSort());
|
||||
} else if(Sort.class.isAssignableFrom(param.getParameterType())) {
|
||||
paramValues[i] = repoRequest.getPagingAndSorting().getSort();
|
||||
} else {
|
||||
String paramName = repoMethod.getParameterNames().get(i);
|
||||
String[] queryParamVals = repoRequest.getRequest().getParameterValues(paramName);
|
||||
if(null == queryParamVals) {
|
||||
if(paramName.startsWith("arg")) {
|
||||
throw new IllegalArgumentException("No @Param annotation found on query method "
|
||||
+ repoMethod.getMethod().getName()
|
||||
+ " for parameter " + param.getParameterName());
|
||||
} else {
|
||||
throw new IllegalArgumentException("No query parameter specified for "
|
||||
+ repoMethod.getMethod().getName() + " param '"
|
||||
+ paramName + "'");
|
||||
}
|
||||
}
|
||||
paramValues[i] = methodParameterConversionService.convert(queryParamVals, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<MethodParameter> methodParams = repoMethod.getParameters();
|
||||
Object[] paramValues = new Object[methodParams.size()];
|
||||
if(!methodParams.isEmpty()) {
|
||||
for(int i = 0; i < paramValues.length; i++) {
|
||||
MethodParameter param = methodParams.get(i);
|
||||
if(Pageable.class.isAssignableFrom(param.getParameterType())) {
|
||||
paramValues[i] = new PageRequest(repoRequest.getPagingAndSorting().getPageNumber(),
|
||||
repoRequest.getPagingAndSorting().getPageSize(),
|
||||
repoRequest.getPagingAndSorting().getSort());
|
||||
} else if(Sort.class.isAssignableFrom(param.getParameterType())) {
|
||||
paramValues[i] = repoRequest.getPagingAndSorting().getSort();
|
||||
} else {
|
||||
String paramName = repoMethod.getParameterNames().get(i);
|
||||
String[] queryParamVals = repoRequest.getRequest().getParameterValues(paramName);
|
||||
if(null == queryParamVals) {
|
||||
if(paramName.startsWith("arg")) {
|
||||
throw new IllegalArgumentException("No @Param annotation found on query method "
|
||||
+ repoMethod.getMethod().getName()
|
||||
+ " for parameter " + param.getParameterName());
|
||||
} else {
|
||||
throw new IllegalArgumentException("No query parameter specified for "
|
||||
+ repoMethod.getMethod().getName() + " param '"
|
||||
+ paramName + "'");
|
||||
}
|
||||
}
|
||||
paramValues[i] = methodParameterConversionService.convert(queryParamVals, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseUriAwareResource resources;
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
Object result = repoMethodInvoker.invokeQueryMethod(repoMethod, paramValues);
|
||||
if(result instanceof Page) {
|
||||
Page page = (Page)result;
|
||||
if(page.hasPreviousPage()) {
|
||||
repoRequest.addPrevLink(page, links);
|
||||
}
|
||||
if(page.hasNextPage()) {
|
||||
repoRequest.addNextLink(page, links);
|
||||
}
|
||||
if(page.hasContent()) {
|
||||
resources = entitiesToResource(repoRequest, page.getContent());
|
||||
} else {
|
||||
resources = new BaseUriAwareResource(EMPTY_RESOURCE_LIST);
|
||||
}
|
||||
} else if(result instanceof Iterable) {
|
||||
resources = entitiesToResource(repoRequest, (Iterable)result);
|
||||
} else if(null == result) {
|
||||
resources = new BaseUriAwareResource(EMPTY_RESOURCE_LIST);
|
||||
} else {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(repoRequest.getPersistentEntity(),
|
||||
result,
|
||||
repoRequest.getBaseUri());
|
||||
per.add(repoRequest.buildEntitySelfLink(result, conversionService));
|
||||
resources = per;
|
||||
}
|
||||
resources.setBaseUri(repoRequest.getBaseUri())
|
||||
.add(links);
|
||||
BaseUriAwareResource resources;
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
Object result = repoMethodInvoker.invokeQueryMethod(repoMethod, paramValues);
|
||||
if(result instanceof Page) {
|
||||
Page page = (Page)result;
|
||||
if(page.hasPreviousPage()) {
|
||||
repoRequest.addPrevLink(page, links);
|
||||
}
|
||||
if(page.hasNextPage()) {
|
||||
repoRequest.addNextLink(page, links);
|
||||
}
|
||||
if(page.hasContent()) {
|
||||
resources = entitiesToResource(repoRequest, page.getContent());
|
||||
} else {
|
||||
resources = new BaseUriAwareResource(EMPTY_RESOURCE_LIST);
|
||||
}
|
||||
} else if(result instanceof Iterable) {
|
||||
resources = entitiesToResource(repoRequest, (Iterable)result);
|
||||
} else if(null == result) {
|
||||
resources = new BaseUriAwareResource(EMPTY_RESOURCE_LIST);
|
||||
} else {
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(repoRequest.getPersistentEntity(),
|
||||
result,
|
||||
repoRequest.getBaseUri());
|
||||
per.add(repoRequest.buildEntitySelfLink(result, conversionService));
|
||||
resources = per;
|
||||
}
|
||||
resources.setBaseUri(repoRequest.getBaseUri())
|
||||
.add(links);
|
||||
|
||||
return resources;
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
value = "/{method}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/x-spring-data-compact+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> queryCompact(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String method)
|
||||
throws ResourceNotFoundException {
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
@RequestMapping(
|
||||
value = "/{method}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/x-spring-data-compact+json"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public Resource<?> queryCompact(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String method)
|
||||
throws ResourceNotFoundException {
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
|
||||
Resource<?> resource = query(repoRequest, method);
|
||||
links.addAll(resource.getLinks());
|
||||
Resource<?> resource = query(repoRequest, method);
|
||||
links.addAll(resource.getLinks());
|
||||
|
||||
if(resource.getContent() instanceof Iterable) {
|
||||
Iterable iter = (Iterable)resource.getContent();
|
||||
for(Object obj : iter) {
|
||||
if(null != obj && obj instanceof Resource) {
|
||||
Resource res = (Resource)obj;
|
||||
links.add(resourceLink(repoRequest, res));
|
||||
}
|
||||
}
|
||||
} else if(resource.getContent() instanceof Resource) {
|
||||
Resource res = (Resource)resource.getContent();
|
||||
links.add(resourceLink(repoRequest, res));
|
||||
}
|
||||
if(resource.getContent() instanceof Iterable) {
|
||||
Iterable iter = (Iterable)resource.getContent();
|
||||
for(Object obj : iter) {
|
||||
if(null != obj && obj instanceof Resource) {
|
||||
Resource res = (Resource)obj;
|
||||
links.add(resourceLink(repoRequest, res));
|
||||
}
|
||||
}
|
||||
} else if(resource.getContent() instanceof Resource) {
|
||||
Resource res = (Resource)resource.getContent();
|
||||
links.add(resourceLink(repoRequest, res));
|
||||
}
|
||||
|
||||
return new Resource<Object>(EMPTY_RESOURCE_LIST, links);
|
||||
}
|
||||
return new Resource<Object>(EMPTY_RESOURCE_LIST, links);
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
value = "/{method}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<? extends Resource<?>> jsonpQuery(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String method)
|
||||
throws ResourceNotFoundException {
|
||||
return jsonpWrapResponse(repoRequest, query(repoRequest, method), HttpStatus.OK);
|
||||
}
|
||||
@RequestMapping(
|
||||
value = "/{method}",
|
||||
method = RequestMethod.GET,
|
||||
produces = {
|
||||
"application/javascript"
|
||||
}
|
||||
)
|
||||
@ResponseBody
|
||||
public JsonpResponse<? extends Resource<?>> jsonpQuery(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String method)
|
||||
throws ResourceNotFoundException {
|
||||
return jsonpWrapResponse(repoRequest, query(repoRequest, method), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private BaseUriAwareResource entitiesToResource(RepositoryRestRequest repoRequest, Iterable entities) {
|
||||
List<Resource<?>> resources = new ArrayList<Resource<?>>();
|
||||
for(Object obj : entities) {
|
||||
if(null == obj) {
|
||||
resources.add(null);
|
||||
break;
|
||||
}
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private BaseUriAwareResource entitiesToResource(RepositoryRestRequest repoRequest, Iterable entities) {
|
||||
List<Resource<?>> resources = new ArrayList<Resource<?>>();
|
||||
for(Object obj : entities) {
|
||||
if(null == obj) {
|
||||
resources.add(null);
|
||||
break;
|
||||
}
|
||||
|
||||
PersistentEntity persistentEntity = repositories.getPersistentEntity(obj.getClass());
|
||||
if(null == persistentEntity) {
|
||||
resources.add(new BaseUriAwareResource<Object>(obj)
|
||||
.setBaseUri(repoRequest.getBaseUri()));
|
||||
continue;
|
||||
}
|
||||
PersistentEntity persistentEntity = repositories.getPersistentEntity(obj.getClass());
|
||||
if(null == persistentEntity) {
|
||||
resources.add(new BaseUriAwareResource<Object>(obj)
|
||||
.setBaseUri(repoRequest.getBaseUri()));
|
||||
continue;
|
||||
}
|
||||
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(persistentEntity, obj, repoRequest.getBaseUri());
|
||||
per.add(repoRequest.buildEntitySelfLink(obj, conversionService));
|
||||
resources.add(per);
|
||||
}
|
||||
return new BaseUriAwareResource(resources)
|
||||
.setBaseUri(repoRequest.getBaseUri());
|
||||
}
|
||||
PersistentEntityResource per = PersistentEntityResource.wrap(persistentEntity, obj, repoRequest.getBaseUri());
|
||||
per.add(repoRequest.buildEntitySelfLink(obj, conversionService));
|
||||
resources.add(per);
|
||||
}
|
||||
return new BaseUriAwareResource(resources)
|
||||
.setBaseUri(repoRequest.getBaseUri());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ import org.springframework.data.rest.repository.json.Jackson2DatatypeHelper;
|
||||
import org.springframework.data.rest.repository.json.PersistentEntityJackson2Module;
|
||||
import org.springframework.data.rest.repository.json.PersistentEntityToJsonSchemaConverter;
|
||||
import org.springframework.data.rest.repository.support.DomainObjectMerger;
|
||||
import org.springframework.data.rest.repository.support.RepositoryEntityLinks;
|
||||
import org.springframework.data.rest.webmvc.BaseUriMethodArgumentResolver;
|
||||
import org.springframework.data.rest.webmvc.PagingAndSortingMethodArgumentResolver;
|
||||
import org.springframework.data.rest.webmvc.PersistentEntityResourceHandlerMethodArgumentResolver;
|
||||
import org.springframework.data.rest.webmvc.RepositoryController;
|
||||
import org.springframework.data.rest.webmvc.RepositoryEntityController;
|
||||
import org.springframework.data.rest.webmvc.RepositoryEntityLinksMethodArgumentResolver;
|
||||
import org.springframework.data.rest.webmvc.RepositoryInformationHandlerMethodArgumentResolver;
|
||||
import org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController;
|
||||
import org.springframework.data.rest.webmvc.RepositoryRestHandlerAdapter;
|
||||
@@ -39,6 +39,7 @@ import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResol
|
||||
import org.springframework.data.rest.webmvc.convert.JsonpResponseHttpMessageConverter;
|
||||
import org.springframework.data.rest.webmvc.convert.UriListHttpMessageConverter;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.hateoas.EntityLinks;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
@@ -145,7 +146,8 @@ public class RepositoryRestMvcConfiguration {
|
||||
repositories().getObject(),
|
||||
config(),
|
||||
domainClassConverter(),
|
||||
defaultConversionService()
|
||||
defaultConversionService(),
|
||||
entityLinks()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -161,7 +163,8 @@ public class RepositoryRestMvcConfiguration {
|
||||
repositories().getObject(),
|
||||
config(),
|
||||
domainClassConverter(),
|
||||
defaultConversionService()
|
||||
defaultConversionService(),
|
||||
entityLinks()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -177,7 +180,8 @@ public class RepositoryRestMvcConfiguration {
|
||||
repositories().getObject(),
|
||||
config(),
|
||||
domainClassConverter(),
|
||||
defaultConversionService()
|
||||
defaultConversionService(),
|
||||
entityLinks()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -193,7 +197,8 @@ public class RepositoryRestMvcConfiguration {
|
||||
repositories().getObject(),
|
||||
config(),
|
||||
domainClassConverter(),
|
||||
defaultConversionService()
|
||||
defaultConversionService(),
|
||||
entityLinks()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -242,8 +247,16 @@ public class RepositoryRestMvcConfiguration {
|
||||
return new RepositoryRestRequestHandlerMethodArgumentResolver();
|
||||
}
|
||||
|
||||
@Bean public RepositoryEntityLinksMethodArgumentResolver entityLinksMethodArgumentResolver() {
|
||||
return new RepositoryEntityLinksMethodArgumentResolver();
|
||||
/**
|
||||
* A special {@link org.springframework.hateoas.EntityLinks} implementation that takes repository and current
|
||||
* configuration into account when generating links.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean public EntityLinks entityLinks() throws Exception {
|
||||
return new RepositoryEntityLinks(repositories().getObject(), config());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,8 +400,7 @@ public class RepositoryRestMvcConfiguration {
|
||||
serverHttpRequestMethodArgumentResolver(),
|
||||
repoInfoMethodArgumentResolver(),
|
||||
repoRequestArgumentResolver(),
|
||||
persistentEntityArgumentResolver(),
|
||||
entityLinksMethodArgumentResolver());
|
||||
persistentEntityArgumentResolver());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user