DATACMNS-426 - RepositoryMetadata now has an isPagingRepository().

Moved getCrudMethods() to RepositoryMetadata to be able to add a isPagingRepository() to the interface as well. Changed DefaultCrudMethods to work with a RepositoryMetadata instead of RepositoryInformation.

DefaultRepositoryInformation now completely delegates to the ResourceMetadata given and not extend it to avoid initialization order issues.
This commit is contained in:
Oliver Gierke
2014-01-20 16:43:25 +01:00
parent 059d398480
commit 0f38612dab
6 changed files with 112 additions and 49 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,13 +71,6 @@ public interface RepositoryInformation extends RepositoryMetadata {
*/
Iterable<Method> getQueryMethods();
/**
* Returns {@link CrudMethods} meta information for the repository.
*
* @return
*/
CrudMethods getCrudMethods();
/**
* Returns the target class method that is backing the given method. This can be necessary if a repository interface
* redeclares a method of the core repository interface (e.g. for transaction behaviour customization). Returns the

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2012 the original author or authors.
* Copyright 2011-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,4 +55,18 @@ public interface RepositoryMetadata {
* @return
*/
Class<?> getReturnedDomainClass(Method method);
/**
* Returns {@link CrudMethods} meta information for the repository.
*
* @return
*/
CrudMethods getCrudMethods();
/**
* Returns whether the repository is a paging one.
*
* @return
*/
boolean isPagingRepository();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,10 @@
package org.springframework.data.repository.core.support;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.core.CrudMethods;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
@@ -32,6 +35,7 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
private final TypeInformation<?> typeInformation;
private final Class<?> repositoryInterface;
private CrudMethods crudMethods;
/**
* Creates a new {@link AbstractRepositoryMetadata}.
@@ -66,4 +70,29 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
public Class<?> getRepositoryInterface() {
return this.repositoryInterface;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#getCrudMethods()
*/
@Override
public CrudMethods getCrudMethods() {
if (this.crudMethods == null) {
this.crudMethods = new DefaultCrudMethods(this);
}
return this.crudMethods;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#isPagingRepository()
*/
@Override
public boolean isPagingRepository() {
Method findAllMethod = getCrudMethods().getFindAllMethod();
return Arrays.asList(findAllMethod.getParameterTypes()).contains(Pageable.class);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,12 +27,11 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.core.CrudMethods;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.util.Assert;
/**
* Default implementation to discover CRUD methods based on a given {@link RepositoryInformation}. Will detect methods
* Default implementation to discover CRUD methods based on the given {@link RepositoryMetadata}. Will detect methods
* exposed in {@link CrudRepository} but also hand crafted CRUD methods that are signature compatible with the ones on
* {@link CrudRepository}.
*
@@ -53,18 +52,18 @@ class DefaultCrudMethods implements CrudMethods {
private final Method deleteMethod;
/**
* Creates a new {@link DefaultCrudMethods} using the given {@link RepositoryInformation}.
* Creates a new {@link DefaultCrudMethods} using the given {@link RepositoryMetadata}.
*
* @param information must not be {@literal null}.
* @param metadata must not be {@literal null}.
*/
public DefaultCrudMethods(RepositoryInformation information) {
public DefaultCrudMethods(RepositoryMetadata metadata) {
Assert.notNull(information, "RepositoryInformation must not be null!");
Assert.notNull(metadata, "RepositoryInformation must not be null!");
this.findOneMethod = selectMostSuitableFindOneMethod(information);
this.findAllMethod = selectMostSuitableFindAllMethod(information);
this.deleteMethod = selectMostSuitableDeleteMethod(information);
this.saveMethod = selectMostSuitableSaveMethod(information);
this.findOneMethod = selectMostSuitableFindOneMethod(metadata);
this.findAllMethod = selectMostSuitableFindAllMethod(metadata);
this.deleteMethod = selectMostSuitableDeleteMethod(metadata);
this.saveMethod = selectMostSuitableSaveMethod(metadata);
}
/**
@@ -74,16 +73,16 @@ class DefaultCrudMethods implements CrudMethods {
* <li>an {@link Object} as first parameter</li>
* </ol>
*
* @param information must not be {@literal null}.
* @param metadata must not be {@literal null}.
* @return the most suitable method or {@literal null} if no method could be found.
*/
@SuppressWarnings("unchecked")
private Method selectMostSuitableSaveMethod(RepositoryInformation information) {
private Method selectMostSuitableSaveMethod(RepositoryMetadata metadata) {
for (Class<?> type : Arrays.asList(information.getDomainType(), Object.class)) {
Method saveMethodCandidate = findMethod(information.getRepositoryInterface(), SAVE, type);
for (Class<?> type : Arrays.asList(metadata.getDomainType(), Object.class)) {
Method saveMethodCandidate = findMethod(metadata.getRepositoryInterface(), SAVE, type);
if (saveMethodCandidate != null) {
return getMostSpecificMethod(saveMethodCandidate, information.getRepositoryInterface());
return getMostSpecificMethod(saveMethodCandidate, metadata.getRepositoryInterface());
}
}
@@ -98,16 +97,16 @@ class DefaultCrudMethods implements CrudMethods {
* <li>an {@link Iterable} as first parameter</li>
* </ol>
*
* @param information must not be {@literal null}.
* @param metadata must not be {@literal null}.
* @return the most suitable method or {@literal null} if no method could be found.
*/
@SuppressWarnings("unchecked")
private Method selectMostSuitableDeleteMethod(RepositoryInformation information) {
private Method selectMostSuitableDeleteMethod(RepositoryMetadata metadata) {
for (Class<?> type : Arrays.asList(information.getIdType(), Serializable.class, Iterable.class)) {
Method candidate = findMethod(information.getRepositoryInterface(), DELETE, type);
for (Class<?> type : Arrays.asList(metadata.getIdType(), Serializable.class, Iterable.class)) {
Method candidate = findMethod(metadata.getRepositoryInterface(), DELETE, type);
if (candidate != null) {
return getMostSpecificMethod(candidate, information.getRepositoryInterface());
return getMostSpecificMethod(candidate, metadata.getRepositoryInterface());
}
}
@@ -122,23 +121,23 @@ class DefaultCrudMethods implements CrudMethods {
* <li>no parameters</li>
* </ol>
*
* @param information must not be {@literal null}.
* @param metadata must not be {@literal null}.
* @return the most suitable method or {@literal null} if no method could be found.
*/
@SuppressWarnings("unchecked")
private Method selectMostSuitableFindAllMethod(RepositoryInformation information) {
private Method selectMostSuitableFindAllMethod(RepositoryMetadata metadata) {
for (Class<?> type : Arrays.asList(Pageable.class, Sort.class)) {
if (hasMethod(information.getRepositoryInterface(), FIND_ALL, type)) {
if (hasMethod(metadata.getRepositoryInterface(), FIND_ALL, type)) {
Method candidate = findMethod(PagingAndSortingRepository.class, FIND_ALL, type);
if (candidate != null) {
return getMostSpecificMethod(candidate, information.getRepositoryInterface());
return getMostSpecificMethod(candidate, metadata.getRepositoryInterface());
}
}
}
if (hasMethod(information.getRepositoryInterface(), FIND_ALL)) {
return getMostSpecificMethod(findMethod(CrudRepository.class, FIND_ALL), information.getRepositoryInterface());
if (hasMethod(metadata.getRepositoryInterface(), FIND_ALL)) {
return getMostSpecificMethod(findMethod(CrudRepository.class, FIND_ALL), metadata.getRepositoryInterface());
}
return null;
@@ -151,16 +150,16 @@ class DefaultCrudMethods implements CrudMethods {
* <li>a {@link Serializable} as first parameter</li>
* </ol>
*
* @param information must not be {@literal null}.
* @param metadata must not be {@literal null}.
* @return the most suitable method or {@literal null} if no method could be found.
*/
@SuppressWarnings("unchecked")
private Method selectMostSuitableFindOneMethod(RepositoryInformation information) {
private Method selectMostSuitableFindOneMethod(RepositoryMetadata metadata) {
for (Class<?> type : Arrays.asList(information.getIdType(), Serializable.class)) {
Method candidate = findMethod(information.getRepositoryInterface(), FIND_ONE, type);
for (Class<?> type : Arrays.asList(metadata.getIdType(), Serializable.class)) {
Method candidate = findMethod(metadata.getRepositoryInterface(), FIND_ONE, type);
if (candidate != null) {
return getMostSpecificMethod(candidate, information.getRepositoryInterface());
return getMostSpecificMethod(candidate, metadata.getRepositoryInterface());
}
}

View File

@@ -44,7 +44,7 @@ import org.springframework.util.ClassUtils;
* @author Oliver Gierke
* @author Thomas Darimont
*/
class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements RepositoryInformation {
class DefaultRepositoryInformation implements RepositoryInformation {
@SuppressWarnings("rawtypes") private static final TypeVariable<Class<Repository>>[] PARAMETERS = Repository.class
.getTypeParameters();
@@ -56,7 +56,6 @@ class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements
private final RepositoryMetadata metadata;
private final Class<?> repositoryBaseClass;
private final Class<?> customImplementationClass;
private final CrudMethods crudMethods;
/**
* Creates a new {@link DefaultRepositoryMetadata} for the given repository interface and repository base class.
@@ -68,15 +67,12 @@ class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements
public DefaultRepositoryInformation(RepositoryMetadata metadata, Class<?> repositoryBaseClass,
Class<?> customImplementationClass) {
super(metadata.getRepositoryInterface());
Assert.notNull(metadata);
Assert.notNull(repositoryBaseClass);
this.metadata = metadata;
this.repositoryBaseClass = repositoryBaseClass;
this.customImplementationClass = customImplementationClass;
this.crudMethods = new DefaultCrudMethods(this);
}
/*
@@ -283,11 +279,38 @@ class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryInformation#getCrudMethods()
* @see org.springframework.data.repository.core.RepositoryMetadata#getRepositoryInterface()
*/
@Override
public Class<?> getRepositoryInterface() {
return metadata.getRepositoryInterface();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#getReturnedDomainClass(java.lang.reflect.Method)
*/
@Override
public Class<?> getReturnedDomainClass(Method method) {
return metadata.getReturnedDomainClass(method);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#getCrudMethods()
*/
@Override
public CrudMethods getCrudMethods() {
return crudMethods;
return metadata.getCrudMethods();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.RepositoryMetadata#isPagingRepository()
*/
@Override
public boolean isPagingRepository() {
return metadata.isPagingRepository();
}
/**