DATACMNS-406 - Tighten contract for RepositoryMetadata implementations.
We now resolve the domain and id-types eagerly within the constructor of AbstractRepositoryMetadata implementations to prevent a RepositoryMetadata instance to be created in an invalid state. Pulled-up repositoryInterface property to AbstractRepositoryMetadata. Original pull request: #58.
This commit is contained in:
committed by
Oliver Gierke
parent
09b8989a7f
commit
b96f613b98
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2013 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,10 +26,12 @@ import org.springframework.util.Assert;
|
||||
* Base class for {@link RepositoryMetadata} implementations.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
|
||||
|
||||
private final TypeInformation<?> typeInformation;
|
||||
private final Class<?> repositoryInterface;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractRepositoryMetadata}.
|
||||
@@ -40,6 +42,8 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
|
||||
|
||||
Assert.notNull(repositoryInterface, "Given type must not be null!");
|
||||
Assert.isTrue(repositoryInterface.isInterface(), "Given type must be an interface!");
|
||||
|
||||
this.repositoryInterface = repositoryInterface;
|
||||
this.typeInformation = ClassTypeInformation.from(repositoryInterface);
|
||||
}
|
||||
|
||||
@@ -54,4 +58,11 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
|
||||
|
||||
return Iterable.class.isAssignableFrom(rawType) ? returnTypeInfo.getComponentType().getType() : rawType;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getRepositoryInterface()
|
||||
*/
|
||||
public Class<?> getRepositoryInterface() {
|
||||
return this.repositoryInterface;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* Copyright 2011-2013 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,13 +26,15 @@ import org.springframework.util.Assert;
|
||||
* {@link RepositoryDefinition} annotation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata {
|
||||
|
||||
private static final String NO_ANNOTATION_FOUND = String.format("Interface must be annotated with @%s!",
|
||||
RepositoryDefinition.class.getName());
|
||||
|
||||
private final Class<?> repositoryInterface;
|
||||
private final Class<? extends Serializable> idType;
|
||||
private final Class<?> domainType;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AnnotationRepositoryMetadata} instance looking up repository types from a
|
||||
@@ -41,34 +43,59 @@ public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata {
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
*/
|
||||
public AnnotationRepositoryMetadata(Class<?> repositoryInterface) {
|
||||
|
||||
super(repositoryInterface);
|
||||
Assert.isTrue(repositoryInterface.isAnnotationPresent(RepositoryDefinition.class), NO_ANNOTATION_FOUND);
|
||||
this.repositoryInterface = repositoryInterface;
|
||||
|
||||
this.idType = resolveIdType(repositoryInterface);
|
||||
this.domainType = resolveDomainType(repositoryInterface);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getIdClass()
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getIdType()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends Serializable> getIdType() {
|
||||
RepositoryDefinition annotation = repositoryInterface.getAnnotation(RepositoryDefinition.class);
|
||||
return annotation == null ? null : annotation.idClass();
|
||||
return this.idType;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getDomainClass()
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getDomainType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getDomainType() {
|
||||
RepositoryDefinition annotation = repositoryInterface.getAnnotation(RepositoryDefinition.class);
|
||||
return annotation == null ? null : annotation.domainClass();
|
||||
return this.domainType;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getRepositoryInterface()
|
||||
/**
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
* @return the resolved domain type, never {@literal null}.
|
||||
*/
|
||||
public Class<?> getRepositoryInterface() {
|
||||
return repositoryInterface;
|
||||
private Class<? extends Serializable> resolveIdType(Class<?> repositoryInterface) {
|
||||
|
||||
Assert.notNull(repositoryInterface, "Repository interface must not be null!");
|
||||
|
||||
RepositoryDefinition annotation = repositoryInterface.getAnnotation(RepositoryDefinition.class);
|
||||
Assert.isTrue(annotation != null && annotation.idClass() != null,
|
||||
String.format("Could not resolve id type of %s!", repositoryInterface));
|
||||
|
||||
return annotation.idClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
* @return the resolved domain type, never {@literal null}.
|
||||
*/
|
||||
private Class<?> resolveDomainType(Class<?> repositoryInterface) {
|
||||
|
||||
Assert.notNull(repositoryInterface, "Repository interface must not be null!");
|
||||
|
||||
RepositoryDefinition annotation = repositoryInterface.getAnnotation(RepositoryDefinition.class);
|
||||
Assert.isTrue(annotation != null && annotation.domainClass() != null,
|
||||
String.format("Could not resolve domain type of %s!", repositoryInterface));
|
||||
|
||||
return annotation.domainClass();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.util.ClassUtils;
|
||||
* Default implementation of {@link RepositoryInformation}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements RepositoryInformation {
|
||||
|
||||
@@ -78,15 +79,6 @@ class DefaultRepositoryInformation extends AbstractRepositoryMetadata implements
|
||||
this.crudMethods = new DefaultCrudMethods(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getRepositoryInterface()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getRepositoryInterface() {
|
||||
return metadata.getRepositoryInterface();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getDomainClass()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -28,10 +28,15 @@ import org.springframework.util.Assert;
|
||||
* about domain and id class.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata {
|
||||
|
||||
private final Class<?> repositoryInterface;
|
||||
private static final String MUST_BE_A_REPOSITORY = String.format("Given type must be assignable to %s!",
|
||||
Repository.class);
|
||||
|
||||
private final Class<? extends Serializable> idType;
|
||||
private final Class<?> domainType;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultRepositoryMetadata} for the given repository interface.
|
||||
@@ -41,38 +46,57 @@ public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata {
|
||||
public DefaultRepositoryMetadata(Class<?> repositoryInterface) {
|
||||
|
||||
super(repositoryInterface);
|
||||
Assert.isTrue(repositoryInterface.isInterface());
|
||||
Assert.isTrue(Repository.class.isAssignableFrom(repositoryInterface));
|
||||
this.repositoryInterface = repositoryInterface;
|
||||
Assert.isTrue(Repository.class.isAssignableFrom(repositoryInterface), MUST_BE_A_REPOSITORY);
|
||||
|
||||
this.idType = resolveIdType(repositoryInterface);
|
||||
this.domainType = resolveDomainType(repositoryInterface);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getRepositoryInterface()
|
||||
*/
|
||||
public Class<?> getRepositoryInterface() {
|
||||
|
||||
return repositoryInterface;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getDomainClass()
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getDomainType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getDomainType() {
|
||||
|
||||
Class<?>[] arguments = resolveTypeArguments(repositoryInterface, Repository.class);
|
||||
return arguments == null ? null : arguments[0];
|
||||
return this.domainType;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryMetadata#getIdClass()
|
||||
* @see org.springframework.data.repository.core.RepositoryMetadata#getIdType()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<? extends Serializable> getIdType() {
|
||||
return this.idType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
* @return the resolved domain type, never {@literal null}.
|
||||
*/
|
||||
private Class<?> resolveDomainType(Class<?> repositoryInterface) {
|
||||
|
||||
Assert.notNull(repositoryInterface, "Repository interface must not be null!");
|
||||
|
||||
Class<?>[] arguments = resolveTypeArguments(repositoryInterface, Repository.class);
|
||||
return (Class<? extends Serializable>) (arguments == null ? null : arguments[1]);
|
||||
Assert.isTrue(arguments != null && arguments[0] != null,
|
||||
String.format("Could not resolve domain type of %s!", repositoryInterface));
|
||||
|
||||
return arguments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
* @return the resolved id type, never {@literal null}.
|
||||
*/
|
||||
private Class<? extends Serializable> resolveIdType(Class<?> repositoryInterface) {
|
||||
|
||||
Assert.notNull(repositoryInterface, "Repository interface must not be null!");
|
||||
|
||||
Class<?>[] arguments = resolveTypeArguments(repositoryInterface, Repository.class);
|
||||
Assert.isTrue(arguments != null && arguments[1] != null,
|
||||
String.format("Could not resolve id type of %s!", repositoryInterface));
|
||||
|
||||
return (Class<? extends Serializable>) arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user