DATACMNS-166 - Improved API in Repositories / RepositoryFactoryInformation.

Renamed methods in RepositoryMetadata to be consistent with EntityMetadata. Changed return type of RepositoryMetadata.getIdType() to Class<? extends Serializable>. 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.
This commit is contained in:
Oliver Gierke
2012-05-02 19:38:14 +02:00
parent 7f6c03d36a
commit 5b0cb1a572
21 changed files with 311 additions and 157 deletions

View File

@@ -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<? extends Serializable> 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.

View File

@@ -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<? extends Serializable> 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();
}

View File

@@ -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<? extends Serializable> 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;

View File

@@ -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<? extends Serializable> getIdType() {
Class<?>[] arguments = resolveTypeArguments(repositoryInterface, Repository.class);
return arguments == null ? null : arguments[1];
return (Class<? extends Serializable>) (arguments == null ? null : arguments[1]);
}
}

View File

@@ -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<T extends Repository<S, ID>,
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<S, ID> getEntityInformation() {
RepositoryMetadata repositoryMetadata = factory.getRepositoryMetadata(repositoryInterface);
return (EntityInformation<S, ID>) factory.getEntityInformation(repositoryMetadata.getDomainClass());
return (EntityInformation<S, ID>) 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<? extends T> getRepositoryInterface() {
return repositoryInterface;
* @see org.springframework.data.repository.core.support.RepositoryFactoryInformation#getQueryMethods()
*/
public List<QueryMethod> 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<? extends T> getObjectType() {
return (Class<? extends T>) (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() {

View File

@@ -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<T, ID extends Serializable> {
EntityInformation<T, ID> 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<? extends Repository<T, ID>> getRepositoryInterface();
RepositoryInformation getRepositoryInformation();
/**
* Returns all {@link QueryMethod}s declared for that repository.
*
* @return
*/
List<QueryMethod> getQueryMethods();
}

View File

@@ -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<QueryCreationListener<?>> queryPostProcessors = new ArrayList<QueryCreationListener<?>>();
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<QueryMethod> 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<RepositoryQuery> {
private List<QueryMethod> queryMethods = new ArrayList<QueryMethod>();
/**
* Returns all {@link QueryMethod}s.
*
* @return
*/
public List<QueryMethod> 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());
}
}
}

View File

@@ -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

View File

@@ -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<T extends ConversionService & ConverterRegistr
*/
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
EntityInformation<?, Serializable> info = repositories.getEntityInformationFor(targetType.getType());
RepositoryInformation info = repositories.getRepositoryInformationFor(targetType.getType());
CrudRepository<?, Serializable> repository = repositories.getRepositoryFor(info);
CrudRepository<?, Serializable> repository = repositories.getRepositoryFor(targetType.getType());
Serializable id = conversionService.convert(source, info.getIdType());
return repository.findOne(id);
}
@@ -77,8 +77,8 @@ public class DomainClassConverter<T extends ConversionService & ConverterRegistr
return false;
}
return conversionService.canConvert(sourceType.getType(), repositories
.getEntityInformationFor(targetType.getType()).getIdType());
return conversionService.canConvert(sourceType.getType(),
repositories.getRepositoryInformationFor(targetType.getType()).getIdType());
}
/*

View File

@@ -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,14 +16,12 @@
package org.springframework.data.repository.support;
import java.io.Serializable;
import java.util.Map.Entry;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.RepositoryInformation;
/**
* Simple helper class to use Hades DAOs to provide {@link java.beans.PropertyEditor}s for domain classes. To get this
@@ -55,15 +53,15 @@ public class DomainClassPropertyEditorRegistrar implements PropertyEditorRegistr
*/
public void registerCustomEditors(PropertyEditorRegistry registry) {
for (Entry<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>> entry : repositories) {
for (Class<?> domainClass : repositories) {
EntityInformation<Object, Serializable> entityInformation = entry.getKey();
CrudRepository<Object, Serializable> repository = entry.getValue();
RepositoryInformation repositoryInformation = repositories.getRepositoryInformationFor(domainClass);
CrudRepository<Object, Serializable> repository = repositories.getRepositoryFor(domainClass);
DomainClassPropertyEditor<Object, Serializable> editor = new DomainClassPropertyEditor<Object, Serializable>(
repository, entityInformation, registry);
repository, repositories.getEntityInformationFor(repositoryInformation.getDomainType()), registry);
registry.registerCustomEditor(entityInformation.getJavaType(), editor);
registry.registerCustomEditor(repositoryInformation.getDomainType(), editor);
}
}

View File

@@ -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<Entry<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>>> {
public class Repositories implements Iterable<Class<?>> {
static final Repositories NONE = new Repositories();
private final Map<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>> repositories = new HashMap<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>>();
private final Map<Class<?>, RepositoryFactoryInformation<Object, Serializable>> domainClassToBeanName = new HashMap<Class<?>, RepositoryFactoryInformation<Object, Serializable>>();
private final Map<RepositoryFactoryInformation<Object, Serializable>, CrudRepository<Object, Serializable>> repositories = new HashMap<RepositoryFactoryInformation<Object, Serializable>, CrudRepository<Object, Serializable>>();
/**
* Constructor to create the {@link #NONE} instance.
@@ -62,17 +65,18 @@ public class Repositories implements
Collection<RepositoryFactoryInformation> providers = BeanFactoryUtils.beansOfTypeIncludingAncestors(factory,
RepositoryFactoryInformation.class).values();
for (RepositoryFactoryInformation entry : providers) {
for (RepositoryFactoryInformation<Object, Serializable> info : providers) {
EntityInformation<Object, Serializable> metadata = entry.getEntityInformation();
Class repositoryInterface = entry.getRepositoryInterface();
RepositoryInformation information = info.getRepositoryInformation();
Class repositoryInterface = information.getRepositoryInterface();
if (CrudRepository.class.isAssignableFrom(repositoryInterface)) {
Class<CrudRepository<Object, Serializable>> objectType = repositoryInterface;
CrudRepository<Object, Serializable> 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 <T, S extends Serializable> CrudRepository<T, S> getRepositoryFor(Class<?> domainClass) {
return (CrudRepository<T, S>) repositories.get(getEntityInformationFor(domainClass));
return (CrudRepository<T, S>) 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 <T, S extends Serializable> CrudRepository<T, S> getRepositoryFor(EntityInformation<T, S> entityInformation) {
return (CrudRepository<T, S>) repositories.get(entityInformation);
public <T, S extends Serializable> EntityInformation<T, S> getEntityInformationFor(Class<?> domainClass) {
RepositoryFactoryInformation<Object, Serializable> information = getRepoInfoFor(domainClass);
return information == null ? null : (EntityInformation<T, S>) 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 <T, S extends Serializable> EntityInformation<T, S> getEntityInformationFor(Class<?> domainClass) {
public RepositoryInformation getRepositoryInformationFor(Class<?> domainClass) {
for (EntityInformation<?, Serializable> information : repositories.keySet()) {
if (domainClass.equals(information.getJavaType())) {
return (EntityInformation<T, S>) information;
RepositoryFactoryInformation<Object, Serializable> 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<QueryMethod> getQueryMethodsFor(Class<?> domainClass) {
RepositoryFactoryInformation<Object, Serializable> information = getRepoInfoFor(domainClass);
return information == null ? Collections.<QueryMethod> emptyList() : information.getQueryMethods();
}
private RepositoryFactoryInformation<Object, Serializable> getRepoInfoFor(Class<?> domainClass) {
Assert.notNull(domainClass);
for (RepositoryFactoryInformation<Object, Serializable> 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<Entry<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>>> iterator() {
return repositories.entrySet().iterator();
public Iterator<Class<?>> iterator() {
return domainClassToBeanName.keySet().iterator();
}
}

View File

@@ -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<Object>(null);
}
@Test
public void considersEntityNewIfGetIdReturnsNull() throws Exception {
EntityInformation<Object, Serializable> metadata = new DummyAbstractEntityInformation(Object.class);
EntityInformation<Object, Serializable> metadata = new DummyEntityInformation<Object>(Object.class);
assertThat(metadata.isNew(null), is(true));
assertThat(metadata.isNew(new Object()), is(false));
}

View File

@@ -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<? extends Serializable> getIdType() {
return null;
}
public Class<?> getDomainClass() {
public Class<?> getDomainType() {
return null;
}

View File

@@ -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)

View File

@@ -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")

View File

@@ -22,14 +22,14 @@ import java.io.Serializable;
*
* @author Oliver Gierke
*/
public class DummyAbstractEntityInformation<T> extends AbstractEntityInformation<T, Serializable> {
public class DummyEntityInformation<T> extends AbstractEntityInformation<T, Serializable> {
/**
* 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<T> domainClass) {
public DummyEntityInformation(Class<T> domainClass) {
super(domainClass);
}

View File

@@ -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<Person> entityInformation = new DummyAbstractEntityInformation<Person>(Person.class);
when(information.getRepositoryInterface()).thenReturn((Class) PersonRepository.class);
when(information.getDomainType()).thenReturn((Class) Person.class);
when(information.getIdType()).thenReturn((Class) Serializable.class);
EntityInformation<Person, Serializable> entityInformation = new DummyEntityInformation<Person>(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));

View File

@@ -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<User, Long> information;
@Mock
RepositoryFactoryInformation<User, Long> provider;
RepositoryFactoryInformation<User, Serializable> provider;
@Before
@SuppressWarnings({ "unchecked", "rawtypes" })
public void setUp() {
EntityInformation<User, Serializable> information = new DummyEntityInformation<User>(User.class);
RepositoryInformation repositoryInformation = new DummyRepositoryInformation(UserRepository.class);
converter = new DomainClassConverter(service);
providers = new HashMap<String, RepositoryFactoryInformation>();
@@ -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<User, Long> provider) {
RepositoryFactoryInformation<User, Serializable> provider) {
Map<String, UserRepository> map = getBeanAsMap(repository);
when(context.getBeansOfType(UserRepository.class)).thenReturn(map);

View File

@@ -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<Entity, Long> information;
@Mock
RepositoryFactoryInformation<Entity, Long> provider;
RepositoryFactoryInformation<Entity, Serializable> provider;
DomainClassPropertyEditor<Entity, Long> reference;
DomainClassPropertyEditor<Entity, Serializable> 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<Entity, Serializable> entityInformation = new DummyEntityInformation<Entity>(Entity.class);
RepositoryInformation repositoryInformation = new DummyRepositoryInformation(EntityRepository.class);
when(provider.getEntityInformation()).thenReturn(entityInformation);
when(provider.getRepositoryInformation()).thenReturn(repositoryInformation);
Map<String, EntityRepository> map = getBeanAsMap(repository);
when(context.getBeansOfType(EntityRepository.class)).thenReturn(map);
reference = new DomainClassPropertyEditor<Entity, Long>(repository, information, registry);
reference = new DomainClassPropertyEditor<Entity, Serializable>(repository, entityInformation, registry);
}
@Test
@@ -109,7 +111,7 @@ public class DomainClassPropertyEditorRegistrarUnitTests {
}
private static interface EntityRepository extends CrudRepository<Entity, Long> {
private static interface EntityRepository extends CrudRepository<Entity, Serializable> {
}

View File

@@ -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<? extends Serializable> 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<Method> getQueryMethods() {
return Collections.emptySet();
}
public Method getTargetClassMethod(Method method) {
return method;
}
}

View File

@@ -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<T, S> getEntityInformation() {
return new EntityInformation<T, S>() {
public Class<T> getJavaType() {
return (Class<T>) repositoryMetadata.getDomainClass();
}
public boolean isNew(T entity) {
return false;
}
public S getId(T entity) {
return null;
}
public Class<S> getIdType() {
return (Class<S>) repositoryMetadata.getIdClass();
}
};
return (EntityInformation) new DummyEntityInformation(repositoryMetadata.getDomainType());
}
@SuppressWarnings("unchecked")
public Class<? extends Repository<T, S>> getRepositoryInterface() {
return (Class<? extends Repository<T, S>>) repositoryMetadata.getRepositoryInterface();
public RepositoryInformation getRepositoryInformation() {
return new DummyRepositoryInformation(repositoryMetadata.getRepositoryInterface());
}
public List<QueryMethod> getQueryMethods() {
return Collections.emptyList();
}
}