DATAJPA-19 - Added Hades extensions module.
Added DomainClassPropertyEditor and DomainClassConverter to automatically bind domain classes to Spring MVC controller methods. Same applies to PageableArgumentResolver. Polished up some generics. Introduced RepositoryFactoryInformation interface being implemented by RepositoryFactorySupport that allows the extension components to get access to the raw factories, access EntityInformation of it and then find out about the repository interface to lookup the actual repository instance.
This commit is contained in:
@@ -89,7 +89,7 @@ public class QueryMethod {
|
||||
}
|
||||
|
||||
|
||||
public EntityMetadata<?> getEntityMetadata() {
|
||||
public EntityMetadata<?> getEntityInformation() {
|
||||
|
||||
return new EntityMetadata() {
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -24,8 +26,8 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class AbstractEntityInformation<T> implements
|
||||
EntityInformation<T> {
|
||||
public abstract class AbstractEntityInformation<T, ID extends Serializable> implements
|
||||
EntityInformation<T, ID> {
|
||||
|
||||
private final Class<T> domainClass;
|
||||
|
||||
|
||||
@@ -15,13 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Extension of {@link EntityMetadata} to add functionality to query information
|
||||
* of entity instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityInformation<T> extends EntityMetadata<T> {
|
||||
public interface EntityInformation<T, ID extends Serializable> extends EntityMetadata<T> {
|
||||
|
||||
/**
|
||||
* Returns whether the given entity is considered to be new.
|
||||
@@ -38,5 +40,12 @@ public interface EntityInformation<T> extends EntityMetadata<T> {
|
||||
* @param entity must never be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
Object getId(T entity);
|
||||
ID getId(T entity);
|
||||
|
||||
/**
|
||||
* Returns the type of the id of the entity.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<ID> getIdType();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
|
||||
|
||||
@@ -25,18 +28,21 @@ import org.springframework.data.domain.Persistable;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class PersistableEntityInformation<T extends Persistable> extends
|
||||
AbstractEntityInformation<T> {
|
||||
public class PersistableEntityInformation<T extends Persistable<ID>, ID extends Serializable> extends
|
||||
AbstractEntityInformation<T, ID> {
|
||||
|
||||
private Class<ID> idClass;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PersistableEntityInformation}.
|
||||
*
|
||||
* @param domainClass
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PersistableEntityInformation(Class<T> domainClass) {
|
||||
|
||||
super(domainClass);
|
||||
this.idClass = (Class<ID>) GenericTypeResolver.resolveTypeArgument(domainClass, Persistable.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +67,15 @@ public class PersistableEntityInformation<T extends Persistable> extends
|
||||
* org.springframework.data.repository.support.IdAware#getId(java.lang.Object
|
||||
* )
|
||||
*/
|
||||
public Object getId(T entity) {
|
||||
public ID getId(T entity) {
|
||||
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
|
||||
*/
|
||||
public Class<ID> getIdType() {
|
||||
return this.idClass;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
@@ -31,8 +33,8 @@ import org.springframework.util.Assert;
|
||||
* @author Oliver Gierke
|
||||
* @param <T> the type of the repository
|
||||
*/
|
||||
public abstract class RepositoryFactoryBeanSupport<T extends Repository<?, ?>>
|
||||
implements FactoryBean<T>, InitializingBean {
|
||||
public abstract class RepositoryFactoryBeanSupport<T extends Repository<S, ID>, S, ID extends Serializable>
|
||||
implements InitializingBean, RepositoryFactoryInformation<S, ID>, FactoryBean<T> {
|
||||
|
||||
private RepositoryFactorySupport factory;
|
||||
|
||||
@@ -75,6 +77,25 @@ public abstract class RepositoryFactoryBeanSupport<T extends Repository<?, ?>>
|
||||
this.customImplementation = customImplementation;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityMetadataProvider#getEntityMetadata()
|
||||
*/
|
||||
public EntityInformation<S, ID> getEntityInformation() {
|
||||
|
||||
RepositoryMetadata repositoryMetadata = factory.getRepositoryMetadata(repositoryInterface);
|
||||
return (EntityInformation<S, ID>) factory.getEntityInformation(repositoryMetadata.getDomainClass());
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryFactoryInformation#getRepositoryInterface()
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends T> getRepositoryInterface() {
|
||||
|
||||
return repositoryInterface;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2011 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 org.springframework.data.repository.Repository;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for components that can provide {@link EntityInformation} this
|
||||
* interface
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface RepositoryFactoryInformation<T, ID extends Serializable> {
|
||||
|
||||
/**
|
||||
* Returns {@link EntityInformation} the repository factory is using.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EntityInformation<T, ID> getEntityInformation();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the interface of the {@link Repository} the factory will create.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<? extends Repository<T, ID>> getRepositoryInterface();
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.repository.support;
|
||||
|
||||
import static org.springframework.util.ReflectionUtils.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -124,8 +125,7 @@ public abstract class RepositoryFactorySupport {
|
||||
Object customImplementation) {
|
||||
|
||||
RepositoryMetadata metadata =
|
||||
new DefaultRepositoryMetadata(repositoryInterface,
|
||||
getRepositoryBaseClass(repositoryInterface));
|
||||
getRepositoryMetadata(repositoryInterface);
|
||||
|
||||
validate(metadata, customImplementation);
|
||||
|
||||
@@ -145,6 +145,29 @@ public abstract class RepositoryFactorySupport {
|
||||
|
||||
return (T) result.getProxy();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the {@link RepositoryMetadata} for the given repository interface.
|
||||
*
|
||||
* @param repositoryInterface
|
||||
* @return
|
||||
*/
|
||||
protected RepositoryMetadata getRepositoryMetadata(Class<?> repositoryInterface) {
|
||||
|
||||
return new DefaultRepositoryMetadata(repositoryInterface, getRepositoryBaseClass(repositoryInterface));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the {@link EntityInformation} for the given domain class.
|
||||
*
|
||||
* @param <T> the entity type
|
||||
* @param <ID> the id type
|
||||
* @param domainClass
|
||||
* @return
|
||||
*/
|
||||
public abstract <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
@@ -32,8 +34,8 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class TransactionalRepositoryFactoryBeanSupport<T extends Repository<?, ?>>
|
||||
extends RepositoryFactoryBeanSupport<T> implements BeanFactoryAware {
|
||||
public abstract class TransactionalRepositoryFactoryBeanSupport<T extends Repository<S, ID>, S, ID extends Serializable>
|
||||
extends RepositoryFactoryBeanSupport<T, S, ID> implements BeanFactoryAware {
|
||||
|
||||
private String transactionManagerName = TxUtils.DEFAULT_TRANSACTION_MANAGER;
|
||||
private RepositoryProxyPostProcessor txPostProcessor;
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.data.repository.support;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
@@ -38,14 +40,14 @@ public class AbstractEntityInformationUnitTests {
|
||||
@Test
|
||||
public void considersEntityNewIfGetIdReturnsNull() throws Exception {
|
||||
|
||||
EntityInformation<Object> metadata =
|
||||
EntityInformation<Object, Serializable> metadata =
|
||||
new DummyAbstractEntityInformation(Object.class);
|
||||
assertThat(metadata.isNew(null), is(true));
|
||||
assertThat(metadata.isNew(new Object()), is(false));
|
||||
}
|
||||
|
||||
private static class DummyAbstractEntityInformation extends
|
||||
AbstractEntityInformation<Object> {
|
||||
AbstractEntityInformation<Object, Serializable> {
|
||||
|
||||
public DummyAbstractEntityInformation(Class<Object> domainClass) {
|
||||
|
||||
@@ -60,9 +62,18 @@ public class AbstractEntityInformationUnitTests {
|
||||
* org.springframework.data.repository.support.EntityMetadata#getId(
|
||||
* java.lang.Object)
|
||||
*/
|
||||
public Object getId(Object entity) {
|
||||
public Serializable getId(Object entity) {
|
||||
|
||||
return entity == null ? null : entity.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
|
||||
*/
|
||||
@Override
|
||||
public Class<Serializable> getIdType() {
|
||||
|
||||
return Serializable.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.springframework.data.domain.Persistable;
|
||||
public class PersistableEntityInformationUnitTests {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
static final PersistableEntityInformation<Persistable> metadata =
|
||||
new PersistableEntityInformation<Persistable>(Persistable.class);
|
||||
static final PersistableEntityInformation metadata =
|
||||
new PersistableEntityInformation(Persistable.class);
|
||||
|
||||
@Mock
|
||||
Persistable<Long> persistable;
|
||||
@@ -64,8 +64,8 @@ public class PersistableEntityInformationUnitTests {
|
||||
@Test
|
||||
public void returnsGivenClassAsEntityType() throws Exception {
|
||||
|
||||
PersistableEntityInformation<PersistableEntity> info =
|
||||
new PersistableEntityInformation<PersistableEntity>(
|
||||
PersistableEntityInformation<PersistableEntity, Long> info =
|
||||
new PersistableEntityInformation<PersistableEntity, Long>(
|
||||
PersistableEntity.class);
|
||||
|
||||
assertEquals(PersistableEntity.class, info.getJavaType());
|
||||
|
||||
@@ -62,6 +62,16 @@ public class RepositoryFactorySupportUnitTests {
|
||||
}
|
||||
|
||||
class DummyRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(
|
||||
Class<T> domainClass) {
|
||||
|
||||
return mock(EntityInformation.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
|
||||
Reference in New Issue
Block a user