public ResponseEntity<? extends ResourceSupport> createPropertyReference(
final RootResourceInformation resourceInformation, final HttpMethod requestMethod,
final @RequestBody Resources<Object> incoming, @BackendId Serializable id, @PathVariable String property)
throws Exception {
final RepositoryInvoker invoker = resourceInformation.getInvoker();
Function<ReferencedProperty, ResourceSupport> handler = new Function<ReferencedProperty, ResourceSupport>() {
@Override
public ResourceSupport apply(ReferencedProperty prop) throws HttpRequestMethodNotSupportedException {
Class<?> propertyType = prop.property.getType();
if (prop.property.isCollectionLike()) {
Collection<Object> coll = CollectionFactory.createCollection(propertyType, 0);
// Either load the exist collection to add to it (PATCH)
if (HttpMethod.PATCH.equals(requestMethod)) {
coll = (Collection<Object>) prop.propertyValue;
}
// Add to the existing collection
for (Link l : incoming.getLinks()) {
Object propVal = loadPropertyValue(prop.propertyType, l);
coll.add(propVal);
}
prop.wrapper.setProperty(prop.property, coll);
} else if (prop.property.isMap()) {
Map<String, Object> m = CollectionFactory.createMap(propertyType, 0);
// Either load the exist collection to add to it (PATCH)
if (HttpMethod.PATCH.equals(requestMethod)) {
m = (Map<String, Object>) prop.propertyValue;
}
// Add to the existing collection
for (Link l : incoming.getLinks()) {
Object propVal = loadPropertyValue(prop.propertyType, l);
m.put(l.getRel(), propVal);
}
prop.wrapper.setProperty(prop.property, m);
} else {
if (HttpMethod.PATCH.equals(requestMethod)) {
throw new HttpRequestMethodNotSupportedException(HttpMethod.PATCH.name(), new String[] { "PATCH" },
"Cannot PATCH 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));
prop.wrapper.setProperty(prop.property, propVal);
}
publisher.publishEvent(new BeforeLinkSaveEvent(prop.wrapper.getBean(), prop.propertyValue));
Object result = invoker.invokeSave(prop.wrapper.getBean());
publisher.publishEvent(new AfterLinkSaveEvent(result, prop.propertyValue));
return null;
}
};