DATAREST-416 - Switched to IdentifierAccessor API where needed.
We now use the newly introduced IdentifierAccessor API to make sure we benefit from store specific optimizations when looking up identifier values. Added some user class lookups to make sure the projection and resource mapping lookup works if proxies types are handed around.
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Map.Entry;
|
|||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.data.rest.core.projection.ProjectionDefinitions;
|
import org.springframework.data.rest.core.projection.ProjectionDefinitions;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,10 +154,11 @@ public class ProjectionDefinitionConfiguration implements ProjectionDefinitions
|
|||||||
|
|
||||||
Assert.notNull(sourceType, "Source type must not be null!");
|
Assert.notNull(sourceType, "Source type must not be null!");
|
||||||
|
|
||||||
|
Class<?> userType = ClassUtils.getUserClass(sourceType);
|
||||||
Map<String, Class<?>> result = new HashMap<String, Class<?>>();
|
Map<String, Class<?>> result = new HashMap<String, Class<?>>();
|
||||||
|
|
||||||
for (Entry<ProjectionDefinitionKey, Class<?>> entry : projectionDefinitions.entrySet()) {
|
for (Entry<ProjectionDefinitionKey, Class<?>> entry : projectionDefinitions.entrySet()) {
|
||||||
if (entry.getKey().sourceType.isAssignableFrom(sourceType)) {
|
if (entry.getKey().sourceType.isAssignableFrom(userType)) {
|
||||||
result.put(entry.getKey().name, entry.getValue());
|
result.put(entry.getKey().name, entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.springframework.data.rest.core.support.RepositoriesUtils;
|
|||||||
import org.springframework.hateoas.RelProvider;
|
import org.springframework.hateoas.RelProvider;
|
||||||
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +90,7 @@ public class RepositoryResourceMappings implements ResourceMappings {
|
|||||||
public ResourceMetadata getMappingFor(Class<?> type) {
|
public ResourceMetadata getMappingFor(Class<?> type) {
|
||||||
|
|
||||||
Assert.notNull(type, "Type must not be null!");
|
Assert.notNull(type, "Type must not be null!");
|
||||||
return cache.get(type);
|
return cache.get(ClassUtils.getUserClass(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void populateCache(Repositories repositories) {
|
private final void populateCache(Repositories repositories) {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
|
|||||||
final List<EmbeddedWrapper> associationProjections = new ArrayList<EmbeddedWrapper>();
|
final List<EmbeddedWrapper> associationProjections = new ArrayList<EmbeddedWrapper>();
|
||||||
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
|
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
|
||||||
final AssociationLinks associationLinks = new AssociationLinks(mappings);
|
final AssociationLinks associationLinks = new AssociationLinks(mappings);
|
||||||
final ResourceMetadata metadata = mappings.getMappingFor(instance.getClass());
|
final ResourceMetadata metadata = mappings.getMappingFor(entity.getType());
|
||||||
|
|
||||||
entity.doWithAssociations(new SimpleAssociationHandler() {
|
entity.doWithAssociations(new SimpleAssociationHandler() {
|
||||||
|
|
||||||
@@ -197,8 +197,7 @@ public class PersistentEntityResourceAssembler implements ResourceAssembler<Obje
|
|||||||
instanceType));
|
instanceType));
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
|
Object id = entity.getIdentifierAccessor(instance).getIdentifier();
|
||||||
Object id = accessor.getProperty(entity.getIdProperty());
|
|
||||||
|
|
||||||
Link resourceLink = entityLinks.linkToSingleResource(entity.getType(), id);
|
Link resourceLink = entityLinks.linkToSingleResource(entity.getType(), id);
|
||||||
return new Link(resourceLink.getHref(), Link.REL_SELF);
|
return new Link(resourceLink.getHref(), Link.REL_SELF);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.springframework.context.ApplicationEventPublisher;
|
|||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
import org.springframework.core.CollectionFactory;
|
import org.springframework.core.CollectionFactory;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
import org.springframework.data.mapping.IdentifierAccessor;
|
||||||
import org.springframework.data.mapping.PersistentEntity;
|
import org.springframework.data.mapping.PersistentEntity;
|
||||||
import org.springframework.data.mapping.PersistentProperty;
|
import org.springframework.data.mapping.PersistentProperty;
|
||||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||||
@@ -209,10 +210,8 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
|||||||
if (prop.property.isCollectionLike()) {
|
if (prop.property.isCollectionLike()) {
|
||||||
for (Object obj : (Iterable<?>) prop.propertyValue) {
|
for (Object obj : (Iterable<?>) prop.propertyValue) {
|
||||||
|
|
||||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(obj);
|
IdentifierAccessor accessor = prop.entity.getIdentifierAccessor(obj);
|
||||||
String sId = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
if (propertyId.equals(accessor.getIdentifier().toString())) {
|
||||||
|
|
||||||
if (propertyId.equals(sId)) {
|
|
||||||
|
|
||||||
PersistentEntityResource resource = assembler.toResource(obj);
|
PersistentEntityResource resource = assembler.toResource(obj);
|
||||||
headers.set("Content-Location", resource.getId().getHref());
|
headers.set("Content-Location", resource.getId().getHref());
|
||||||
@@ -222,10 +221,8 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
|||||||
} else if (prop.property.isMap()) {
|
} else if (prop.property.isMap()) {
|
||||||
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) prop.propertyValue).entrySet()) {
|
for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) prop.propertyValue).entrySet()) {
|
||||||
|
|
||||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(entry.getValue());
|
IdentifierAccessor accessor = prop.entity.getIdentifierAccessor(entry.getValue());
|
||||||
String sId = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
if (propertyId.equals(accessor.getIdentifier().toString())) {
|
||||||
|
|
||||||
if (propertyId.equals(sId)) {
|
|
||||||
|
|
||||||
PersistentEntityResource resource = assembler.toResource(entry.getValue());
|
PersistentEntityResource resource = assembler.toResource(entry.getValue());
|
||||||
headers.set("Content-Location", resource.getId().getHref());
|
headers.set("Content-Location", resource.getId().getHref());
|
||||||
@@ -401,8 +398,9 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
|||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
Object obj = itr.next();
|
Object obj = itr.next();
|
||||||
|
|
||||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(obj);
|
IdentifierAccessor accessor = prop.entity.getIdentifierAccessor(obj);
|
||||||
String s = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
String s = accessor.getIdentifier().toString();
|
||||||
|
|
||||||
if (propertyId.equals(s)) {
|
if (propertyId.equals(s)) {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
}
|
}
|
||||||
@@ -412,8 +410,10 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
|||||||
Iterator<Object> itr = m.keySet().iterator();
|
Iterator<Object> itr = m.keySet().iterator();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
Object key = itr.next();
|
Object key = itr.next();
|
||||||
PersistentPropertyAccessor accessor = prop.entity.getPropertyAccessor(m.get(key));
|
|
||||||
String s = accessor.getProperty(prop.entity.getIdProperty()).toString();
|
IdentifierAccessor accessor = prop.entity.getIdentifierAccessor(m.get(key));
|
||||||
|
String s = accessor.getIdentifier().toString();
|
||||||
|
|
||||||
if (propertyId.equals(s)) {
|
if (propertyId.equals(s)) {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user