Adding initial CRUD repository implementation.

This commit is contained in:
Michael Nitschinger
2013-05-29 12:22:27 +02:00
parent a307d8f595
commit 4c320a9473
11 changed files with 376 additions and 1 deletions

View File

@@ -22,6 +22,8 @@
package com.couchbase.spring.core;
import com.couchbase.spring.core.convert.CouchbaseConverter;
import java.util.Collection;
public interface CouchbaseOperations {
@@ -114,6 +116,14 @@ public interface CouchbaseOperations {
*/
<T> T findById(String id, Class<T> entityClass);
/**
* Checks if the given document exists.
*
* @param id the unique ID of the document.
* @return whether the document could be found or not.
*/
boolean exists(String id);
/**
* Remove the given object from the bucket by id.
*
@@ -139,4 +149,11 @@ public interface CouchbaseOperations {
* @return
*/
<T> T execute(BucketCallback<T> action);
/**
* Returns the underlying {@link CouchbaseConverter}
* @return
*/
CouchbaseConverter getConverter();
}

View File

@@ -189,6 +189,17 @@ public class CouchbaseTemplate implements CouchbaseOperations {
}
}
@Override
public boolean exists(final String id) {
String result = execute(new BucketCallback<String>() {
@Override
public String doInBucket() {
return (String) client.get(id);
}
});
return result == null ? false : true;
}
/**
* Make sure the given object is not a iterable.
*
@@ -207,5 +218,8 @@ public class CouchbaseTemplate implements CouchbaseOperations {
return resolved == null ? ex : resolved;
}
@Override
public CouchbaseConverter getConverter() {
return couchbaseConverter;
}
}

View File

@@ -0,0 +1,12 @@
package com.couchbase.spring.repository;
import org.springframework.data.repository.CrudRepository;
import java.io.Serializable;
/**
* Couchbase specific {@link org.springframework.data.repository.Repository}
* interface.
*/
public interface CouchbaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
}

View File

@@ -0,0 +1,9 @@
package com.couchbase.spring.repository.query;
import org.springframework.data.repository.core.EntityInformation;
import java.io.Serializable;
public interface CouchbaseEntityInformation<T, ID extends Serializable> extends EntityInformation<T, ID> {
}

View File

@@ -0,0 +1,54 @@
package com.couchbase.spring.repository.support;
import com.couchbase.spring.core.CouchbaseOperations;
import com.couchbase.spring.core.mapping.CouchbasePersistentEntity;
import com.couchbase.spring.core.mapping.CouchbasePersistentProperty;
import com.couchbase.spring.repository.query.CouchbaseEntityInformation;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.util.Assert;
import java.io.Serializable;
/**
* Factory to create {@link CouchbaseRepository} instances.
*/
public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
private final CouchbaseOperations couchbaseOperations;
private final MappingContext<? extends CouchbasePersistentEntity<?>,
CouchbasePersistentProperty> mappingContext;
public CouchbaseRepositoryFactory(final CouchbaseOperations couchbaseOperations) {
Assert.notNull(couchbaseOperations);
this.couchbaseOperations = couchbaseOperations;
mappingContext = couchbaseOperations.getConverter().getMappingContext();
}
@Override
public <T, ID extends Serializable> CouchbaseEntityInformation<T, ID>
getEntityInformation(Class<T> domainClass) {
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
if(entity == null) {
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
domainClass.getName()));
}
return new MappingCouchbaseEntityInformation<T, ID>((CouchbasePersistentEntity<T>) entity);
}
@Override
protected Object getTargetRepository(RepositoryMetadata metadata) {
CouchbaseEntityInformation<?, Serializable> entityInformation =
getEntityInformation(metadata.getDomainType());
return new SimpleCouchbaseRepository(entityInformation, couchbaseOperations);
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata repositoryMetadata) {
return SimpleCouchbaseRepository.class;
}
}

View File

@@ -0,0 +1,36 @@
package com.couchbase.spring.repository.support;
import com.couchbase.spring.core.CouchbaseOperations;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.util.Assert;
import java.io.Serializable;
public class CouchbaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
RepositoryFactoryBeanSupport<T, S, ID> {
private CouchbaseOperations operations;
public void setCouchbaseOperations(CouchbaseOperations operations) {
this.operations = operations;
setMappingContext(operations.getConverter().getMappingContext());
}
@Override
protected RepositoryFactorySupport createRepositoryFactory() {
return getFactoryInstance(operations);
}
private RepositoryFactorySupport getFactoryInstance(CouchbaseOperations operations) {
return new CouchbaseRepositoryFactory(operations);
}
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
Assert.notNull(operations, "CouchbaseTemplate must not be null!");
}
}

View File

@@ -0,0 +1,42 @@
package com.couchbase.spring.repository.support;
import com.couchbase.spring.core.mapping.CouchbasePersistentEntity;
import com.couchbase.spring.core.mapping.CouchbasePersistentProperty;
import com.couchbase.spring.repository.query.CouchbaseEntityInformation;
import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.repository.core.support.AbstractEntityInformation;
import java.io.Serializable;
public class MappingCouchbaseEntityInformation<T, ID extends Serializable>
extends AbstractEntityInformation<T, ID>
implements CouchbaseEntityInformation<T, ID> {
private final CouchbasePersistentEntity<T> entityMetadata;
public MappingCouchbaseEntityInformation(CouchbasePersistentEntity<T> entity) {
super(entity.getType());
entityMetadata = entity;
}
@Override
public ID getId(T entity) {
CouchbasePersistentProperty idProperty = entityMetadata.getIdProperty();
if(idProperty == null) {
return null;
}
try {
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Class<ID> getIdType() {
return (Class<ID>) entityMetadata.getIdProperty().getType();
}
}

View File

@@ -0,0 +1,109 @@
package com.couchbase.spring.repository.support;
import com.couchbase.spring.core.CouchbaseOperations;
import com.couchbase.spring.repository.CouchbaseRepository;
import com.couchbase.spring.repository.query.CouchbaseEntityInformation;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Repository base implementation for Couchbase.
*/
public class SimpleCouchbaseRepository<T, ID extends Serializable> implements CouchbaseRepository<T, ID> {
private final CouchbaseOperations couchbaseOperations;
private final CouchbaseEntityInformation<T, String> entityInformation;
public SimpleCouchbaseRepository(CouchbaseEntityInformation<T, String> metadata, CouchbaseOperations couchbaseOperations) {
Assert.notNull(couchbaseOperations);
Assert.notNull(metadata);
entityInformation = metadata;
this.couchbaseOperations = couchbaseOperations;
}
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null!");
couchbaseOperations.save(entity);
return entity;
}
@Override
public <S extends T> Iterable<S> save(Iterable<S> entities) {
Assert.notNull(entities, "The given Iterable of entities must not be null!");
List<S> result = new ArrayList<S>();
for(S entity : entities) {
save(entity);
result.add(entity);
}
return result;
}
@Override
public T findOne(ID id) {
Assert.notNull(id, "The given id must not be null!");
return couchbaseOperations.findById(id.toString(), entityInformation.getJavaType());
}
@Override
public boolean exists(ID id) {
Assert.notNull(id, "The given id must not be null!");
return couchbaseOperations.exists(id.toString());
}
@Override
public void delete(ID id) {
Assert.notNull(id, "The given id must not be null!");
couchbaseOperations.remove(id.toString());
}
@Override
public void delete(T entity) {
Assert.notNull(entity, "The given id must not be null!");
couchbaseOperations.remove(entity);
}
@Override
public void delete(Iterable<? extends T> entities) {
Assert.notNull(entities, "The given Iterable of entities must not be null!");
for (T entity: entities) {
couchbaseOperations.remove(entity);
}
}
@Override
public Iterable<T> findAll() {
throw new UnsupportedOperationException("findAll is not supported in the current version!");
}
@Override
public Iterable<T> findAll(Iterable<ID> ids) {
throw new UnsupportedOperationException("findAll is not supported in the current version!");
}
@Override
public long count() {
throw new UnsupportedOperationException("count is not supported in the current version!");
}
@Override
public void deleteAll() {
throw new UnsupportedOperationException("deleteAll is not supported in the current version!");
}
protected CouchbaseOperations getCouchbaseOperations() {
return couchbaseOperations;
}
protected CouchbaseEntityInformation<T, String> getEntityInformation() {
return entityInformation;
}
}