DATACMNS-673 - Enhanced RepositoryMetadata to allow returning alternative domain types.
In case a RepositoryMetadata implementation alters the domain type the repository is actually handling, we still have to be able to find the repository based on the type originally declared in the repository. The newly introduced getAlternativeDomainTypes() is now used by Repositories to register a repository for all types returned by that method, too, so that this reverse lookup still works.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,9 @@ package org.springframework.data.repository.core;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
|
||||
/**
|
||||
* Metadata for repository interfaces.
|
||||
@@ -69,4 +72,15 @@ public interface RepositoryMetadata {
|
||||
* @return
|
||||
*/
|
||||
boolean isPagingRepository();
|
||||
|
||||
/**
|
||||
* Returns the set of types the repository shall be discoverable for when trying to look up a repository by domain
|
||||
* type.
|
||||
*
|
||||
* @see Repositories#getRepositoryFor(Class)
|
||||
* @return the set of types the repository shall be discoverable for when trying to look up a repository by domain
|
||||
* type, must not be {@literal null}.
|
||||
* @since 1.11
|
||||
*/
|
||||
Set<Class<?>> getAlternativeDomainTypes();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.springframework.data.repository.core.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.Repository;
|
||||
@@ -115,6 +117,15 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
|
||||
return Arrays.asList(findAllMethod.getParameterTypes()).contains(Pageable.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getAlternativeDomainTypes()
|
||||
*/
|
||||
@Override
|
||||
public Set<Class<?>> getAlternativeDomainTypes() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively unwraps well known wrapper types from the given {@link TypeInformation}.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -315,6 +315,15 @@ class DefaultRepositoryInformation implements RepositoryInformation {
|
||||
return metadata.isPagingRepository();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getAlternativeDomainTypes()
|
||||
*/
|
||||
@Override
|
||||
public Set<Class<?>> getAlternativeDomainTypes() {
|
||||
return metadata.getAlternativeDomainTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given method's parameters to match the ones of the given base class method. Matches generic arguments
|
||||
* agains the ones bound in the given repository interface.
|
||||
|
||||
@@ -18,9 +18,11 @@ package org.springframework.data.repository.support;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
@@ -79,19 +81,33 @@ public class Repositories implements Iterable<Class<?>> {
|
||||
populateRepositoryFactoryInformation(factory);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void populateRepositoryFactoryInformation(ListableBeanFactory factory) {
|
||||
|
||||
for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, RepositoryFactoryInformation.class,
|
||||
false, false)) {
|
||||
cacheRepositoryFactory(name);
|
||||
}
|
||||
}
|
||||
|
||||
RepositoryFactoryInformation repositoryFactoryInformation = beanFactory.getBean(name,
|
||||
RepositoryFactoryInformation.class);
|
||||
Class<?> userDomainType = ClassUtils.getUserClass(repositoryFactoryInformation.getRepositoryInformation()
|
||||
.getDomainType());
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private synchronized void cacheRepositoryFactory(String name) {
|
||||
|
||||
this.repositoryFactoryInfos.put(userDomainType, repositoryFactoryInformation);
|
||||
this.repositoryBeanNames.put(userDomainType, BeanFactoryUtils.transformedBeanName(name));
|
||||
RepositoryFactoryInformation repositoryFactoryInformation = beanFactory.getBean(name,
|
||||
RepositoryFactoryInformation.class);
|
||||
Class<?> domainType = ClassUtils.getUserClass(repositoryFactoryInformation.getRepositoryInformation()
|
||||
.getDomainType());
|
||||
|
||||
RepositoryInformation information = repositoryFactoryInformation.getRepositoryInformation();
|
||||
Set<Class<?>> alternativeDomainTypes = information.getAlternativeDomainTypes();
|
||||
String beanName = BeanFactoryUtils.transformedBeanName(name);
|
||||
|
||||
Set<Class<?>> typesToRegister = new HashSet<Class<?>>(alternativeDomainTypes.size() + 1);
|
||||
typesToRegister.add(domainType);
|
||||
typesToRegister.addAll(alternativeDomainTypes);
|
||||
|
||||
for (Class<?> type : typesToRegister) {
|
||||
this.repositoryFactoryInfos.put(type, repositoryFactoryInformation);
|
||||
this.repositoryBeanNames.put(type, beanName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user