From 5b0cb1a572e52ec1e2ba1e9e70785a9d48d27114 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 2 May 2012 19:38:14 +0200 Subject: [PATCH] DATACMNS-166 - Improved API in Repositories / RepositoryFactoryInformation. Renamed methods in RepositoryMetadata to be consistent with EntityMetadata. Changed return type of RepositoryMetadata.getIdType() to Class. Changed RepositoryFactoryInformation interface to expose RepositoryInformation rather than just the repository interface. Added exposing the QueryMethod instances as well. Adapter Repositories wrapper and it's clients accordingly. --- .../repository/core/RepositoryMetadata.java | 9 ++- .../support/AnnotationRepositoryMetadata.java | 8 ++- .../support/DefaultRepositoryInformation.java | 15 ++-- .../support/DefaultRepositoryMetadata.java | 11 +-- .../support/RepositoryFactoryBeanSupport.java | 61 ++++++++-------- .../support/RepositoryFactoryInformation.java | 21 ++++-- .../support/RepositoryFactorySupport.java | 42 ++++++++++- .../data/repository/query/QueryMethod.java | 4 +- .../support/DomainClassConverter.java | 12 ++-- .../DomainClassPropertyEditorRegistrar.java | 16 ++--- .../data/repository/support/Repositories.java | 71 +++++++++++++------ .../AbstractEntityInformationUnitTests.java | 6 +- .../AbstractRepositoryMetadataUnitTests.java | 6 +- ...AnnotationRepositoryMetadataUnitTests.java | 4 +- .../DefaultRepositoryMetadataUnitTests.java | 12 ++-- ...ation.java => DummyEntityInformation.java} | 6 +- .../DomainClassConverterIntegrationTests.java | 19 +++-- .../DomainClassConverterUnitTests.java | 16 +++-- ...ClassPropertyEditorRegistrarUnitTests.java | 24 ++++--- .../support/DummyRepositoryInformation.java | 69 ++++++++++++++++++ .../support/RepositoriesUnitTests.java | 36 ++++------ 21 files changed, 311 insertions(+), 157 deletions(-) rename spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/{DummyAbstractEntityInformation.java => DummyEntityInformation.java} (83%) create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DummyRepositoryInformation.java diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/RepositoryMetadata.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/RepositoryMetadata.java index 5fd19ee37..4747c74b8 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/RepositoryMetadata.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/RepositoryMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -15,6 +15,7 @@ */ package org.springframework.data.repository.core; +import java.io.Serializable; import java.lang.reflect.Method; import java.util.Collection; @@ -28,18 +29,16 @@ public interface RepositoryMetadata { /** * Returns the id class the given class is declared for. * - * @param clazz * @return the id class of the entity managed by the repository for or {@code null} if none found. */ - Class getIdClass(); + Class getIdType(); /** * Returns the domain class the repository is declared for. * - * @param clazz * @return the domain class the repository is handling or {@code null} if none found. */ - Class getDomainClass(); + Class getDomainType(); /** * Returns the repository interface. diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadata.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadata.java index ebacb2372..55af87cfb 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadata.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -15,6 +15,8 @@ */ package org.springframework.data.repository.core.support; +import java.io.Serializable; + import org.springframework.data.repository.RepositoryDefinition; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.util.Assert; @@ -48,7 +50,7 @@ public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata { * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryMetadata#getIdClass() */ - public Class getIdClass() { + public Class getIdType() { RepositoryDefinition annotation = repositoryInterface.getAnnotation(RepositoryDefinition.class); return annotation == null ? null : annotation.idClass(); } @@ -57,7 +59,7 @@ public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata { * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryMetadata#getDomainClass() */ - public Class getDomainClass() { + public Class getDomainType() { RepositoryDefinition annotation = repositoryInterface.getAnnotation(RepositoryDefinition.class); return annotation == null ? null : annotation.domainClass(); } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java index affad102c..1220c8d30 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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,7 @@ package org.springframework.data.repository.core.support; import static org.springframework.core.GenericTypeResolver.*; import static org.springframework.data.repository.util.ClassUtils.*; +import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -83,16 +84,16 @@ class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryMetadata#getDomainClass() */ - public Class getDomainClass() { - return metadata.getDomainClass(); + public Class getDomainType() { + return metadata.getDomainType(); } /* * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryMetadata#getIdClass() */ - public Class getIdClass() { - return metadata.getIdClass(); + public Class getIdType() { + return metadata.getIdType(); } /* @@ -287,8 +288,8 @@ class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements */ private boolean matchesGenericType(TypeVariable variable, Class parameterType) { - Class entityType = getDomainClass(); - Class idClass = getIdClass(); + Class entityType = getDomainType(); + Class idClass = getIdType(); if (ID_TYPE_NAME.equals(variable.getName()) && parameterType.isAssignableFrom(idClass)) { return true; diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java index e69727ba4..18861322a 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -17,6 +17,8 @@ package org.springframework.data.repository.core.support; import static org.springframework.core.GenericTypeResolver.*; +import java.io.Serializable; + import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.util.Assert; @@ -57,7 +59,7 @@ public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata { * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryMetadata#getDomainClass() */ - public Class getDomainClass() { + public Class getDomainType() { Class[] arguments = resolveTypeArguments(repositoryInterface, Repository.class); return arguments == null ? null : arguments[0]; @@ -67,9 +69,10 @@ public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata { * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryMetadata#getIdClass() */ - public Class getIdClass() { + @SuppressWarnings("unchecked") + public Class getIdType() { Class[] arguments = resolveTypeArguments(repositoryInterface, Repository.class); - return arguments == null ? null : arguments[1]; + return (Class) (arguments == null ? null : arguments[1]); } } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java index f098f0c71..e97df11d8 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 the original author or authors. + * Copyright 2008-2012 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,6 +16,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.List; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; @@ -23,9 +24,11 @@ import org.springframework.beans.factory.annotation.Required; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.NamedQueries; +import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; +import org.springframework.data.repository.query.QueryMethod; import org.springframework.util.Assert; /** @@ -86,60 +89,62 @@ public abstract class RepositoryFactoryBeanSupport, this.namedQueries = namedQueries; } - /* (non-Javadoc) - * @see org.springframework.data.repository.support.EntityMetadataProvider#getEntityMetadata() - */ + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.RepositoryFactoryInformation#getEntityInformation() + */ @SuppressWarnings("unchecked") public EntityInformation getEntityInformation() { RepositoryMetadata repositoryMetadata = factory.getRepositoryMetadata(repositoryInterface); - return (EntityInformation) factory.getEntityInformation(repositoryMetadata.getDomainClass()); + return (EntityInformation) factory.getEntityInformation(repositoryMetadata.getDomainType()); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.RepositoryFactoryInformation#getRepositoryInformation() + */ + public RepositoryInformation getRepositoryInformation() { + RepositoryMetadata metadata = factory.getRepositoryMetadata(repositoryInterface); + return this.factory.getRepositoryInformation(metadata, + customImplementation == null ? null : customImplementation.getClass()); } /* (non-Javadoc) - * @see org.springframework.data.repository.support.RepositoryFactoryInformation#getRepositoryInterface() - */ - public Class getRepositoryInterface() { - - return repositoryInterface; + * @see org.springframework.data.repository.core.support.RepositoryFactoryInformation#getQueryMethods() + */ + public List getQueryMethods() { + return factory.getQueryMethods(); } /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.FactoryBean#getObject() - */ + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ public T getObject() { - return factory.getRepository(repositoryInterface, customImplementation); } /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ @SuppressWarnings("unchecked") public Class getObjectType() { - return (Class) (null == repositoryInterface ? Repository.class : repositoryInterface); } /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ public boolean isSingleton() { - return true; } /* * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ public void afterPropertiesSet() { diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryInformation.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryInformation.java index 30e67e096..4ebbeb007 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryInformation.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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,12 +16,16 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.List; -import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.query.QueryMethod; /** - * Interface for components that can provide {@link EntityInformation} this interface + * Interface for components that can provide meta-information about a repository factory, the backing + * {@link EntityInformation} and {@link RepositoryInformation} as well as the {@link QueryMethod}s exposed by the + * repository. * * @author Oliver Gierke */ @@ -35,9 +39,16 @@ public interface RepositoryFactoryInformation { EntityInformation getEntityInformation(); /** - * Returns the interface of the {@link Repository} the factory will create. + * Returns the {@link RepositoryInformation} to determine meta-information about the repository being used. * * @return */ - Class> getRepositoryInterface(); + RepositoryInformation getRepositoryInformation(); + + /** + * Returns all {@link QueryMethod}s declared for that repository. + * + * @return + */ + List getQueryMethods(); } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index 5244fa08e..132f09cce 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2012 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. @@ -54,6 +54,12 @@ public abstract class RepositoryFactorySupport { private List> queryPostProcessors = new ArrayList>(); private NamedQueries namedQueries = PropertiesBasedNamedQueries.EMPTY; + private QueryCollectingQueryCreationListener collectingListener = new QueryCollectingQueryCreationListener(); + + public RepositoryFactorySupport() { + this.queryPostProcessors.add(collectingListener); + } + /** * Sets the strategy of how to lookup a query to execute finders. * @@ -162,10 +168,15 @@ public abstract class RepositoryFactorySupport { * @param customImplementationClass * @return */ - private RepositoryInformation getRepositoryInformation(RepositoryMetadata metadata, Class customImplementationClass) { + protected RepositoryInformation getRepositoryInformation(RepositoryMetadata metadata, + Class customImplementationClass) { return new DefaultRepositoryInformation(metadata, getRepositoryBaseClass(metadata), customImplementationClass); } + protected List getQueryMethods() { + return collectingListener.getQueryMethods(); + } + /** * Returns the {@link EntityInformation} for the given domain class. * @@ -355,4 +366,31 @@ public abstract class RepositoryFactorySupport { return repositoryInformation.isCustomMethod(invocation.getMethod()); } } + + /** + * {@link QueryCreationListener} collecting the {@link QueryMethod}s created for all query methods of the repository + * interface. + * + * @author Oliver Gierke + */ + private static class QueryCollectingQueryCreationListener implements QueryCreationListener { + + private List queryMethods = new ArrayList(); + + /** + * Returns all {@link QueryMethod}s. + * + * @return + */ + public List getQueryMethods() { + return queryMethods; + } + + /* (non-Javadoc) + * @see org.springframework.data.repository.core.support.QueryCreationListener#onCreation(org.springframework.data.repository.query.RepositoryQuery) + */ + public void onCreation(RepositoryQuery query) { + this.queryMethods.add(query.getQueryMethod()); + } + } } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java index 1643ccbd9..57f179894 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 the original author or authors. + * Copyright 2008-2012 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. @@ -127,7 +127,7 @@ public class QueryMethod { */ protected Class getDomainClass() { - Class repositoryDomainClass = metadata.getDomainClass(); + Class repositoryDomainClass = metadata.getDomainType(); Class methodDomainClass = metadata.getReturnedDomainClass(method); return repositoryDomainClass == null || repositoryDomainClass.isAssignableFrom(methodDomainClass) ? methodDomainClass diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java index c307c88f8..0e0e2e623 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 the original author or authors. + * Copyright 2008-2012 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. @@ -26,7 +26,7 @@ import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; /** * {@link org.springframework.core.convert.converter.Converter} to convert arbitrary input into domain classes managed @@ -60,9 +60,9 @@ public class DomainClassConverter info = repositories.getEntityInformationFor(targetType.getType()); + RepositoryInformation info = repositories.getRepositoryInformationFor(targetType.getType()); - CrudRepository repository = repositories.getRepositoryFor(info); + CrudRepository repository = repositories.getRepositoryFor(targetType.getType()); Serializable id = conversionService.convert(source, info.getIdType()); return repository.findOne(id); } @@ -77,8 +77,8 @@ public class DomainClassConverter, CrudRepository> entry : repositories) { + for (Class domainClass : repositories) { - EntityInformation entityInformation = entry.getKey(); - CrudRepository repository = entry.getValue(); + RepositoryInformation repositoryInformation = repositories.getRepositoryInformationFor(domainClass); + CrudRepository repository = repositories.getRepositoryFor(domainClass); DomainClassPropertyEditor editor = new DomainClassPropertyEditor( - repository, entityInformation, registry); + repository, repositories.getEntityInformationFor(repositoryInformation.getDomainType()), registry); - registry.registerCustomEditor(entityInformation.getJavaType(), editor); + registry.registerCustomEditor(repositoryInformation.getDomainType(), editor); } } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/Repositories.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/Repositories.java index 5ae71023e..264007e97 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/Repositories.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/support/Repositories.java @@ -17,16 +17,19 @@ package org.springframework.data.repository.support; import java.io.Serializable; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; -import java.util.Map.Entry; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; +import org.springframework.data.repository.query.QueryMethod; import org.springframework.util.Assert; /** @@ -34,12 +37,12 @@ import org.springframework.util.Assert; * * @author Oliver Gierke */ -public class Repositories implements - Iterable, CrudRepository>> { +public class Repositories implements Iterable> { static final Repositories NONE = new Repositories(); - private final Map, CrudRepository> repositories = new HashMap, CrudRepository>(); + private final Map, RepositoryFactoryInformation> domainClassToBeanName = new HashMap, RepositoryFactoryInformation>(); + private final Map, CrudRepository> repositories = new HashMap, CrudRepository>(); /** * Constructor to create the {@link #NONE} instance. @@ -62,17 +65,18 @@ public class Repositories implements Collection providers = BeanFactoryUtils.beansOfTypeIncludingAncestors(factory, RepositoryFactoryInformation.class).values(); - for (RepositoryFactoryInformation entry : providers) { + for (RepositoryFactoryInformation info : providers) { - EntityInformation metadata = entry.getEntityInformation(); - Class repositoryInterface = entry.getRepositoryInterface(); + RepositoryInformation information = info.getRepositoryInformation(); + Class repositoryInterface = information.getRepositoryInterface(); if (CrudRepository.class.isAssignableFrom(repositoryInterface)) { Class> objectType = repositoryInterface; CrudRepository repository = BeanFactoryUtils.beanOfTypeIncludingAncestors(factory, objectType); - this.repositories.put(metadata, repository); + this.domainClassToBeanName.put(information.getDomainType(), info); + this.repositories.put(info, repository); } } } @@ -84,29 +88,31 @@ public class Repositories implements * @return */ public boolean hasRepositoryFor(Class domainClass) { - return repositories.containsKey(getEntityInformationFor(domainClass)); + return domainClassToBeanName.containsKey(domainClass); } /** * Returns the repository managing the given domain class. * - * @param domainClass + * @param domainClass must not be {@literal null}. * @return */ @SuppressWarnings("unchecked") public CrudRepository getRepositoryFor(Class domainClass) { - return (CrudRepository) repositories.get(getEntityInformationFor(domainClass)); + return (CrudRepository) repositories.get(domainClassToBeanName.get(domainClass)); } /** - * Returns the repository for the given {@link EntityInformation}. + * Returns the {@link EntityInformation} for the given domain class. * - * @param entityInformation - * @return the repository for the given {@link EntityInformation}. + * @param domainClass must not be {@literal null}. + * @return */ @SuppressWarnings("unchecked") - public CrudRepository getRepositoryFor(EntityInformation entityInformation) { - return (CrudRepository) repositories.get(entityInformation); + public EntityInformation getEntityInformationFor(Class domainClass) { + + RepositoryFactoryInformation information = getRepoInfoFor(domainClass); + return information == null ? null : (EntityInformation) information.getEntityInformation(); } /** @@ -116,12 +122,31 @@ public class Repositories implements * @return the {@link EntityInformation} for the given domain class or {@literal null} if no repository registered for * this domain class. */ - @SuppressWarnings("unchecked") - public EntityInformation getEntityInformationFor(Class domainClass) { + public RepositoryInformation getRepositoryInformationFor(Class domainClass) { - for (EntityInformation information : repositories.keySet()) { - if (domainClass.equals(information.getJavaType())) { - return (EntityInformation) information; + RepositoryFactoryInformation information = getRepoInfoFor(domainClass); + return information == null ? null : information.getRepositoryInformation(); + } + + /** + * Returns the {@link QueryMethod}s contained in the repository managing the given domain class. + * + * @param domainClass must not be {@literal null}. + * @return + */ + public List getQueryMethodsFor(Class domainClass) { + + RepositoryFactoryInformation information = getRepoInfoFor(domainClass); + return information == null ? Collections. emptyList() : information.getQueryMethods(); + } + + private RepositoryFactoryInformation getRepoInfoFor(Class domainClass) { + + Assert.notNull(domainClass); + + for (RepositoryFactoryInformation information : repositories.keySet()) { + if (domainClass.equals(information.getEntityInformation().getJavaType())) { + return information; } } @@ -132,7 +157,7 @@ public class Repositories implements * (non-Javadoc) * @see java.lang.Iterable#iterator() */ - public Iterator, CrudRepository>> iterator() { - return repositories.entrySet().iterator(); + public Iterator> iterator() { + return domainClassToBeanName.keySet().iterator(); } } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java index fe00a2bbe..71008561d 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -33,13 +33,13 @@ public class AbstractEntityInformationUnitTests { @Test(expected = IllegalArgumentException.class) public void rejectsNullDomainClass() throws Exception { - new DummyAbstractEntityInformation(null); + new DummyEntityInformation(null); } @Test public void considersEntityNewIfGetIdReturnsNull() throws Exception { - EntityInformation metadata = new DummyAbstractEntityInformation(Object.class); + EntityInformation metadata = new DummyEntityInformation(Object.class); assertThat(metadata.isNew(null), is(true)); assertThat(metadata.isNew(new Object()), is(false)); } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java index 10c0d2c19..759d5a887 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadataUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -111,11 +111,11 @@ public class AbstractRepositoryMetadataUnitTests { super(repositoryInterface); } - public Class getIdClass() { + public Class getIdType() { return null; } - public Class getDomainClass() { + public Class getDomainType() { return null; } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadataUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadataUnitTests.java index 9e2cbf350..bd3de4f2e 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadataUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadataUnitTests.java @@ -34,8 +34,8 @@ public class AnnotationRepositoryMetadataUnitTests { public void handlesRepositoryProxyAnnotationCorrectly() { RepositoryMetadata metadata = new AnnotationRepositoryMetadata(AnnotatedRepository.class); - assertEquals(User.class, metadata.getDomainClass()); - assertEquals(Integer.class, metadata.getIdClass()); + assertEquals(User.class, metadata.getDomainType()); + assertEquals(Integer.class, metadata.getIdType()); } @Test(expected = IllegalArgumentException.class) diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java index e5facbe18..a5cb79843 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -54,24 +54,24 @@ public class DefaultRepositoryMetadataUnitTests { public void looksUpDomainClassCorrectly() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); - assertEquals(User.class, metadata.getDomainClass()); + assertEquals(User.class, metadata.getDomainType()); metadata = new DefaultRepositoryMetadata(SomeDao.class); - assertEquals(User.class, metadata.getDomainClass()); + assertEquals(User.class, metadata.getDomainType()); } @Test public void findsDomainClassOnExtensionOfDaoInterface() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(ExtensionOfUserCustomExtendedDao.class); - assertEquals(User.class, metadata.getDomainClass()); + assertEquals(User.class, metadata.getDomainType()); } @Test public void detectsParameterizedEntitiesCorrectly() { RepositoryMetadata metadata = new DefaultRepositoryMetadata(GenericEntityRepository.class); - assertEquals(GenericEntity.class, metadata.getDomainClass()); + assertEquals(GenericEntity.class, metadata.getDomainType()); } @Test @@ -79,7 +79,7 @@ public class DefaultRepositoryMetadataUnitTests { RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); - assertEquals(Integer.class, metadata.getIdClass()); + assertEquals(Integer.class, metadata.getIdType()); } @SuppressWarnings("unused") diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DummyAbstractEntityInformation.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java similarity index 83% rename from spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DummyAbstractEntityInformation.java rename to spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java index 817c71b86..47d8b472e 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DummyAbstractEntityInformation.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java @@ -22,14 +22,14 @@ import java.io.Serializable; * * @author Oliver Gierke */ -public class DummyAbstractEntityInformation extends AbstractEntityInformation { +public class DummyEntityInformation extends AbstractEntityInformation { /** - * Creates a new {@link DummyAbstractEntityInformation} for the given domain class. + * Creates a new {@link DummyEntityInformation} for the given domain class. * * @param domainClass */ - public DummyAbstractEntityInformation(Class domainClass) { + public DummyEntityInformation(Class domainClass) { super(domainClass); } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java index add88aefe..807c3c051 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java @@ -34,7 +34,9 @@ import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.core.support.DummyAbstractEntityInformation; +import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.core.support.DummyEntityInformation; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; @@ -48,9 +50,11 @@ public class DomainClassConverterIntegrationTests { @Mock @SuppressWarnings("rawtypes") - static RepositoryFactoryBeanSupport factory; + RepositoryFactoryBeanSupport factory; @Mock - static PersonRepository repository; + PersonRepository repository; + @Mock + RepositoryInformation information; @Test @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -66,11 +70,16 @@ public class DomainClassConverterIntegrationTests { beanFactory.registerBeanDefinition("postProcessor", new RootBeanDefinition(PredictingProcessor.class)); beanFactory.registerBeanDefinition("repoFactory", new RootBeanDefinition(RepositoryFactoryBeanSupport.class)); - DummyAbstractEntityInformation entityInformation = new DummyAbstractEntityInformation(Person.class); + when(information.getRepositoryInterface()).thenReturn((Class) PersonRepository.class); + when(information.getDomainType()).thenReturn((Class) Person.class); + when(information.getIdType()).thenReturn((Class) Serializable.class); + + EntityInformation entityInformation = new DummyEntityInformation(Person.class); + when(factory.getObject()).thenReturn(repository); when(factory.getObjectType()).thenReturn(PersonRepository.class); when(factory.getEntityInformation()).thenReturn(entityInformation); - when(factory.getRepositoryInterface()).thenReturn(PersonRepository.class); + when(factory.getRepositoryInformation()).thenReturn(information); GenericApplicationContext context = new GenericApplicationContext(beanFactory); assertThat(context.getBeansOfType(RepositoryFactoryInformation.class).values().size(), is(1)); diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java index 0ff2c6595..f5888a803 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java @@ -20,6 +20,7 @@ import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; +import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -35,6 +36,8 @@ import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.core.support.DummyEntityInformation; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; /** @@ -63,14 +66,15 @@ public class DomainClassConverterUnitTests { @Mock DefaultConversionService service; @Mock - EntityInformation information; - @Mock - RepositoryFactoryInformation provider; + RepositoryFactoryInformation provider; @Before @SuppressWarnings({ "unchecked", "rawtypes" }) public void setUp() { + EntityInformation information = new DummyEntityInformation(User.class); + RepositoryInformation repositoryInformation = new DummyRepositoryInformation(UserRepository.class); + converter = new DomainClassConverter(service); providers = new HashMap(); @@ -78,9 +82,7 @@ public class DomainClassConverterUnitTests { targetDescriptor = TypeDescriptor.valueOf(User.class); when(provider.getEntityInformation()).thenReturn(information); - when(provider.getRepositoryInterface()).thenReturn((Class) UserRepository.class); - when(information.getJavaType()).thenReturn(User.class); - when(information.getIdType()).thenReturn(Long.class); + when(provider.getRepositoryInformation()).thenReturn(repositoryInformation); } @Test @@ -155,7 +157,7 @@ public class DomainClassConverterUnitTests { } private void configureContextToReturnBeans(ApplicationContext context, UserRepository repository, - RepositoryFactoryInformation provider) { + RepositoryFactoryInformation provider) { Map map = getBeanAsMap(repository); when(context.getBeansOfType(UserRepository.class)).thenReturn(map); diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java index 553ea1816..aa0caffd3 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 the original author or authors. + * Copyright 2008-2012 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. @@ -34,6 +34,8 @@ import org.springframework.beans.PropertyEditorRegistry; import org.springframework.context.ApplicationContext; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.core.support.DummyEntityInformation; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; /** @@ -52,23 +54,23 @@ public class DomainClassPropertyEditorRegistrarUnitTests { @Mock EntityRepository repository; @Mock - EntityInformation information; - @Mock - RepositoryFactoryInformation provider; + RepositoryFactoryInformation provider; - DomainClassPropertyEditor reference; + DomainClassPropertyEditor reference; @Before - @SuppressWarnings({ "unchecked", "rawtypes" }) public void setup() { - when(information.getJavaType()).thenReturn(Entity.class); - when(provider.getEntityInformation()).thenReturn(information); - when(provider.getRepositoryInterface()).thenReturn((Class) EntityRepository.class); + EntityInformation entityInformation = new DummyEntityInformation(Entity.class); + RepositoryInformation repositoryInformation = new DummyRepositoryInformation(EntityRepository.class); + + when(provider.getEntityInformation()).thenReturn(entityInformation); + when(provider.getRepositoryInformation()).thenReturn(repositoryInformation); + Map map = getBeanAsMap(repository); when(context.getBeansOfType(EntityRepository.class)).thenReturn(map); - reference = new DomainClassPropertyEditor(repository, information, registry); + reference = new DomainClassPropertyEditor(repository, entityInformation, registry); } @Test @@ -109,7 +111,7 @@ public class DomainClassPropertyEditorRegistrarUnitTests { } - private static interface EntityRepository extends CrudRepository { + private static interface EntityRepository extends CrudRepository { } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DummyRepositoryInformation.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DummyRepositoryInformation.java new file mode 100644 index 000000000..a7b4e6477 --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/DummyRepositoryInformation.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.repository.support; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.Collections; + +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; + +public final class DummyRepositoryInformation implements RepositoryInformation { + + private final RepositoryMetadata metadata; + + public DummyRepositoryInformation(Class repositoryInterface) { + this.metadata = new DefaultRepositoryMetadata(repositoryInterface); + } + + public Class getIdType() { + return metadata.getIdType(); + } + + public Class getDomainType() { + return metadata.getDomainType(); + } + + public Class getRepositoryInterface() { + return metadata.getRepositoryInterface(); + } + + public Class getReturnedDomainClass(Method method) { + return getDomainType(); + } + + public Class getRepositoryBaseClass() { + return getRepositoryInterface(); + } + + public boolean hasCustomMethod() { + return false; + } + + public boolean isCustomMethod(Method method) { + return false; + } + + public Iterable getQueryMethods() { + return Collections.emptySet(); + } + + public Method getTargetClassMethod(Method method) { + return method; + } +} \ No newline at end of file diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java index 6f14a0423..1d45ff16b 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java @@ -22,7 +22,9 @@ import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.junit.Before; @@ -34,9 +36,12 @@ import org.springframework.context.ApplicationContext; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; +import org.springframework.data.repository.core.support.DummyEntityInformation; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; +import org.springframework.data.repository.query.QueryMethod; /** * Unit tests for {@link Repositories}. @@ -112,32 +117,17 @@ public class RepositoriesUnitTests { this.repositoryMetadata = new DefaultRepositoryMetadata(repositoryInterface); } - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings({ "unchecked", "rawtypes" }) public EntityInformation getEntityInformation() { - - return new EntityInformation() { - - public Class getJavaType() { - return (Class) repositoryMetadata.getDomainClass(); - } - - public boolean isNew(T entity) { - return false; - } - - public S getId(T entity) { - return null; - } - - public Class getIdType() { - return (Class) repositoryMetadata.getIdClass(); - } - }; + return (EntityInformation) new DummyEntityInformation(repositoryMetadata.getDomainType()); } - @SuppressWarnings("unchecked") - public Class> getRepositoryInterface() { - return (Class>) repositoryMetadata.getRepositoryInterface(); + public RepositoryInformation getRepositoryInformation() { + return new DummyRepositoryInformation(repositoryMetadata.getRepositoryInterface()); + } + + public List getQueryMethods() { + return Collections.emptyList(); } }