DATACOUCH-21 - Documentation and Formatting improvements
This commit is contained in:
@@ -22,9 +22,11 @@ import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.support.SimpleValueWrapper;
|
||||
|
||||
/**
|
||||
* The CouchbaseCache class implements the Spring Cache interface
|
||||
* on top of Couchbase Server and the Couchbase Java SDK.
|
||||
* The {@link CouchbaseCache} class implements the Spring Cache interface on top of Couchbase Server and the Couchbase
|
||||
* Java SDK.
|
||||
*
|
||||
* @see <a href="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/cache.html">
|
||||
* Official Spring Cache Reference</a>
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseCache implements Cache {
|
||||
@@ -65,7 +67,7 @@ public class CouchbaseCache implements Cache {
|
||||
* @return the actual CouchbaseClient instance.
|
||||
*/
|
||||
public final CouchbaseClient getNativeCache() {
|
||||
return this.client;
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +78,7 @@ public class CouchbaseCache implements Cache {
|
||||
*/
|
||||
public final ValueWrapper get(final Object key) {
|
||||
String documentId = key.toString();
|
||||
Object result = this.client.get(documentId);
|
||||
Object result = client.get(documentId);
|
||||
return (result != null ? new SimpleValueWrapper(result) : null);
|
||||
}
|
||||
|
||||
@@ -88,7 +90,7 @@ public class CouchbaseCache implements Cache {
|
||||
*/
|
||||
public final void put(final Object key, final Object value) {
|
||||
String documentId = key.toString();
|
||||
this.client.set(documentId, 0, value);
|
||||
client.set(documentId, 0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +100,7 @@ public class CouchbaseCache implements Cache {
|
||||
*/
|
||||
public final void evict(final Object key) {
|
||||
String documentId = key.toString();
|
||||
this.client.delete(documentId);
|
||||
client.delete(documentId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +110,7 @@ public class CouchbaseCache implements Cache {
|
||||
* Also note that "flush" may not be enabled on the bucket.
|
||||
*/
|
||||
public final void clear() {
|
||||
this.client.flush();
|
||||
client.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,11 +25,10 @@ import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.support.AbstractCacheManager;
|
||||
|
||||
/**
|
||||
* The CouchbaseCacheManager orchestrates CouchbaseCache instances.
|
||||
* The {@link CouchbaseCacheManager} orchestrates {@link CouchbaseCache} instances.
|
||||
*
|
||||
* Since more than one current CouchbaseClient connection can be used
|
||||
* for caching, the CouchbaseCacheManager orchestrates and handles
|
||||
* them for the Spring Cache abstraction layer.
|
||||
* Since more than one current {@link CouchbaseClient} connection can be used for caching, the
|
||||
* {@link CouchbaseCacheManager} orchestrates and handles them for the Spring Cache abstraction layer.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@@ -55,7 +54,7 @@ public class CouchbaseCacheManager extends AbstractCacheManager {
|
||||
* @return the actual CouchbaseClient instances.
|
||||
*/
|
||||
public final HashMap<String, CouchbaseClient> getClients() {
|
||||
return this.clients;
|
||||
return clients;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +66,7 @@ public class CouchbaseCacheManager extends AbstractCacheManager {
|
||||
protected final Collection<? extends Cache> loadCaches() {
|
||||
Collection<Cache> caches = new LinkedHashSet<Cache>();
|
||||
|
||||
for (Map.Entry<String, CouchbaseClient> cache : this.clients.entrySet()) {
|
||||
for (Map.Entry<String, CouchbaseClient> cache : clients.entrySet()) {
|
||||
caches.add(new CouchbaseCache(cache.getKey(), cache.getValue()));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.couchbase.core.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
@@ -42,12 +42,16 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
|
||||
/**
|
||||
* Return the {@link CouchbaseClient} instance to connect to.
|
||||
*
|
||||
* @throws Exception on Bean construction failure.
|
||||
*/
|
||||
@Bean
|
||||
public abstract CouchbaseClient couchbaseClient() throws Exception;
|
||||
|
||||
/**
|
||||
* Creates a {@link CouchbaseTemplate}.
|
||||
*
|
||||
* @throws Exception on Bean construction failure.
|
||||
*/
|
||||
@Bean
|
||||
public CouchbaseTemplate couchbaseTemplate() throws Exception {
|
||||
@@ -55,8 +59,9 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link MappingCouchbaseConverter} using the configured {@link
|
||||
* #couchbaseMappingContext}.
|
||||
* Creates a {@link MappingCouchbaseConverter} using the configured {@link #couchbaseMappingContext}.
|
||||
*
|
||||
* @throws Exception on Bean construction failure.
|
||||
*/
|
||||
@Bean
|
||||
public MappingCouchbaseConverter mappingCouchbaseConverter() throws Exception {
|
||||
@@ -64,8 +69,9 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CouchbaseMappingContext} equipped with entity classes
|
||||
* scanned from the mapping base package.
|
||||
* Creates a {@link CouchbaseMappingContext} equipped with entity classes scanned from the mapping base package.
|
||||
*
|
||||
* @throws Exception on Bean construction failure.
|
||||
*/
|
||||
@Bean
|
||||
public CouchbaseMappingContext couchbaseMappingContext() throws Exception {
|
||||
@@ -76,12 +82,14 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
|
||||
/**
|
||||
* Scans the mapping base package for classes annotated with {@link Document}.
|
||||
*
|
||||
* @throws ClassNotFoundException if intial entity sets could not be loaded.
|
||||
*/
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
String basePackage = getMappingBasePackage();
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
|
||||
if(StringUtils.hasText(basePackage)) {
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider =
|
||||
new ClassPathScanningCandidateComponentProvider(false);
|
||||
componentProvider.addIncludeFilter(
|
||||
@@ -100,15 +108,14 @@ public abstract class AbstractCouchbaseConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base package to scan for mapped {@link Document}s. Will return
|
||||
* the package name of the configuration class (the concrete class, not this
|
||||
* one here) by default. So if you have a {@code com.acme.AppConfig} extending
|
||||
* {@link AbstractCouchbaseConfiguration} the base package will be considered
|
||||
* {@code com.acme} unless the method is overridden to implement alternate
|
||||
* behavior.
|
||||
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
|
||||
* class (the concrete class, not this one here) by default.
|
||||
*
|
||||
* @return the base package to scan for mapped {@link Document} classes or
|
||||
* {@literal null} to not enable scanning for entities.
|
||||
* <p>So if you have a {@code com.acme.AppConfig} extending {@link AbstractCouchbaseConfiguration} the base package
|
||||
* will be considered {@code com.acme} unless the method is overridden to implement alternate behavior.</p>
|
||||
*
|
||||
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
|
||||
* entities.
|
||||
*/
|
||||
protected String getMappingBasePackage() {
|
||||
return getClass().getPackage().getName();
|
||||
|
||||
@@ -17,12 +17,18 @@
|
||||
package org.springframework.data.couchbase.config;
|
||||
|
||||
/**
|
||||
* Contains default bean names that will be used when no "id" is supplied to the beans.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class BeanNames {
|
||||
static final String MAPPING_CONTEXT = "mappingContext";
|
||||
/**
|
||||
* Refers to the "<couchbase:couchbase />" bean.
|
||||
*/
|
||||
static final String COUCHBASE = "couchbase";
|
||||
static final String DB_FACTORY = "couchbaseDbFactory";
|
||||
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
|
||||
|
||||
/**
|
||||
* Refers to the "<couchbase:template />" bean.
|
||||
*/
|
||||
static final String COUCHBASE_TEMPLATE = "couchbaseTemplate";
|
||||
}
|
||||
|
||||
@@ -28,12 +28,22 @@ import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Enables Parsing of "<couchbase:jmx />" configurations.
|
||||
* Enables Parsing of the "<couchbase:jmx />" configuration bean.
|
||||
*
|
||||
* In order to enable JMX, different JmxComponents need to be registered. The dependency to the original
|
||||
* {@link com.couchbase.client.CouchbaseClient} object is solved by through the "couchbase-ref" attribute.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseJmxParser implements BeanDefinitionParser {
|
||||
|
||||
/**
|
||||
* Parse the element and dispatch the registration of the JMX components.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @param parserContext encapsulates the parsing state and configuration.
|
||||
* @return null, because no bean instance needs to be returned.
|
||||
*/
|
||||
public BeanDefinition parse(final Element element, final ParserContext parserContext) {
|
||||
String name = element.getAttribute("couchbase-ref");
|
||||
if (!StringUtils.hasText(name)) {
|
||||
@@ -43,7 +53,14 @@ public class CouchbaseJmxParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void registerJmxComponents(String refName, Element element, ParserContext parserContext) {
|
||||
/**
|
||||
* Register the JMX components in the context.
|
||||
*
|
||||
* @param refName the reference name to the couchbase client.
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @param parserContext encapsulates the parsing state and configuration.
|
||||
*/
|
||||
protected void registerJmxComponents(final String refName, final Element element, final ParserContext parserContext) {
|
||||
Object eleSource = parserContext.extractSource(element);
|
||||
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
|
||||
|
||||
@@ -53,8 +70,17 @@ public class CouchbaseJmxParser implements BeanDefinitionParser {
|
||||
parserContext.registerComponent(compositeDef);
|
||||
}
|
||||
|
||||
protected void createBeanDefEntry(Class<?> clazz, CompositeComponentDefinition compositeDef,
|
||||
String refName, Object eleSource, ParserContext parserContext) {
|
||||
/**
|
||||
* Creates Bean Definitions for JMX components and adds them as a nested component.
|
||||
*
|
||||
* @param clazz the class type to register.
|
||||
* @param compositeDef component that can hold nested components.
|
||||
* @param refName the reference name to the couchbase client.
|
||||
* @param eleSource source element to reference.
|
||||
* @param parserContext encapsulates the parsing state and configuration.
|
||||
*/
|
||||
protected void createBeanDefEntry(final Class<?> clazz, final CompositeComponentDefinition compositeDef,
|
||||
final String refName, final Object eleSource, final ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
|
||||
builder.getRawBeanDefinition().setSource(eleSource);
|
||||
builder.addConstructorArgReference(refName);
|
||||
|
||||
@@ -24,11 +24,17 @@ import org.springframework.data.repository.config.RepositoryConfigurationExtensi
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Couchbase configuration.
|
||||
*
|
||||
* This handler acts as a container for one or more bean parsers and registers them. During parsing, the elements
|
||||
* get analyzed and the appropriate registered parser is called.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
public void init() {
|
||||
/**
|
||||
* Register bean definition parsers in the namespace handler.
|
||||
*/
|
||||
public final void init() {
|
||||
RepositoryConfigurationExtension extension = new CouchbaseRepositoryConfigurationExtension();
|
||||
|
||||
registerBeanDefinitionParser("repositories", new RepositoryBeanDefinitionParser(extension));
|
||||
|
||||
@@ -31,19 +31,32 @@ import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Parser for "<couchbase:couchbase />" definitions.
|
||||
* Parser for "<couchbase:couchbase />" bean definitions.
|
||||
*
|
||||
* The outcome of this bean definition parser will be a constructed {@link CouchbaseClient}.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
/**
|
||||
* Defines the bean class that will be constructed.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @return the class type to instantiate.
|
||||
*/
|
||||
@Override
|
||||
protected Class getBeanClass(final Element element) {
|
||||
return CouchbaseClient.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the bean definition and build up the bean.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @param bean the builder which builds the bean.
|
||||
*/
|
||||
@Override
|
||||
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
|
||||
String host = element.getAttribute("host");
|
||||
@@ -57,12 +70,30 @@ public class CouchbaseParser extends AbstractSingleBeanDefinitionParser {
|
||||
StringUtils.hasText(password) ? password : CouchbaseFactoryBean.DEFAULT_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the bean ID and assign a default if not set.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @param definition the bean definition to work with.
|
||||
* @param parserContext encapsulates the parsing state and configuration.
|
||||
* @return the ID to work with.
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(final Element element, final AbstractBeanDefinition definition,
|
||||
final ParserContext parserContext) {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of hosts into a URI format that can be used by the {@link CouchbaseClient}.
|
||||
*
|
||||
* To make it simple to use, the list of hosts can be passed in as a comma separated list. This list gets parsed
|
||||
* and converted into a URI format that is suitable for the underlying {@link CouchbaseClient} object.
|
||||
*
|
||||
* @param hosts the host list to convert.
|
||||
* @return the converted list with URIs.
|
||||
*/
|
||||
private List<URI> convertHosts(final String hosts) {
|
||||
String[] split = hosts.split(",");
|
||||
List<URI> nodes = new ArrayList<URI>();
|
||||
|
||||
@@ -25,21 +25,46 @@ import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for "<couchbase:template />" bean definitions.
|
||||
*
|
||||
* The outcome of this bean definition parser will be a constructed {@link CouchbaseTemplate}.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
/**
|
||||
* Resolve the bean ID and assign a default if not set.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @param definition the bean definition to work with.
|
||||
* @param parserContext encapsulates the parsing state and configuration.
|
||||
* @return the ID to work with.
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(final Element element, final AbstractBeanDefinition definition,
|
||||
final ParserContext parserContext) {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_TEMPLATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the bean class that will be constructed.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @return the class type to instantiate.
|
||||
*/
|
||||
@Override
|
||||
protected Class getBeanClass(final Element element) {
|
||||
return CouchbaseTemplate.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the bean definition and build up the bean.
|
||||
*
|
||||
* @param element the XML element which contains the attributes.
|
||||
* @param bean the builder which builds the bean.
|
||||
*/
|
||||
@Override
|
||||
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
|
||||
String converterRef = element.getAttribute("converter-ref");
|
||||
|
||||
@@ -20,8 +20,20 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* Defines the callback which will be wrapped and executed on a bucket.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface BucketCallback<T> {
|
||||
|
||||
/**
|
||||
* The enclosed body will be executed on the connected bucket.
|
||||
*
|
||||
* @return the result of the enclosed execution.
|
||||
* @throws TimeoutException if the enclosed operation timed out.
|
||||
* @throws ExecutionException if the result could not be retrieved because of a thrown exception before.
|
||||
* @throws InterruptedException if the enclosed operation was interrupted.
|
||||
*/
|
||||
T doInBucket() throws TimeoutException, ExecutionException, InterruptedException;
|
||||
|
||||
}
|
||||
|
||||
@@ -35,10 +35,9 @@ import java.util.concurrent.CancellationException;
|
||||
/**
|
||||
* Simple {@link PersistenceExceptionTranslator} for Couchbase.
|
||||
*
|
||||
* Convert the given runtime exception to an appropriate exception from the
|
||||
* {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation
|
||||
* is appropriate: any other exception may have resulted from user code, and should not
|
||||
* be translated.
|
||||
* Convert the given runtime exception to an appropriate exception from the {@code org.springframework.dao} hierarchy.
|
||||
* Return {@literal null} if no translation is appropriate: any other exception may have resulted from user code, and
|
||||
* should not be translated.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
|
||||
@@ -34,76 +34,183 @@ import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Convenient Factory for configuring Couchbase.
|
||||
* Convenient Factory for configuring a {@link CouchbaseClient}.
|
||||
*
|
||||
* To set the properties correctly on the {@link CouchbaseClient} a {@link CouchbaseConnectionFactoryBuilder} is used.
|
||||
* After all properties are set, the client is constructed and used.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseFactoryBean implements FactoryBean<CouchbaseClient>, InitializingBean,
|
||||
DisposableBean, PersistenceExceptionTranslator {
|
||||
|
||||
/**
|
||||
* Defines the default hostname to be used if no other list is supplied.
|
||||
*/
|
||||
public static final String DEFAULT_NODE = "127.0.0.1";
|
||||
|
||||
/**
|
||||
* Defines the default bucket name to be used if no other bucket name is supplied.
|
||||
*/
|
||||
public static final String DEFAULT_BUCKET = "default";
|
||||
|
||||
/**
|
||||
* Defines the password of the default bucket.
|
||||
*/
|
||||
public static final String DEFAULT_PASSWORD = "";
|
||||
|
||||
/**
|
||||
* Holds the enclosed {@link CouchbaseClient}.
|
||||
*/
|
||||
private CouchbaseClient couchbaseClient;
|
||||
private PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
|
||||
private String bucket;
|
||||
private String password;
|
||||
private List<URI> nodes;
|
||||
private CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder();
|
||||
|
||||
/**
|
||||
* The exception translator is used to properly map exceptions to spring-type exceptions.
|
||||
*/
|
||||
private PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator();
|
||||
|
||||
/**
|
||||
* Contains the actual bucket name.
|
||||
*/
|
||||
private String bucket;
|
||||
|
||||
/**
|
||||
* Contains the actual bucket password.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Contains the list of nodes to connect to.
|
||||
*/
|
||||
private List<URI> nodes;
|
||||
|
||||
/**
|
||||
* The builder which allows to customize client settings.
|
||||
*/
|
||||
private final CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder();
|
||||
|
||||
/**
|
||||
* Set the observe poll interval in miliseconds.
|
||||
*
|
||||
* @param interval the observe poll interval.
|
||||
*/
|
||||
public void setObservePollInterval(final int interval) {
|
||||
builder.setObsPollInterval(interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of polls.
|
||||
*
|
||||
* @param max the maximum number of polls.
|
||||
*/
|
||||
public void setObservePollMax(final int max) {
|
||||
builder.setObsPollMax(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reconnect threshold time in seconds.
|
||||
*
|
||||
* @param time the reconnect threshold time.
|
||||
*/
|
||||
public void setReconnectThresholdTime(final int time) {
|
||||
builder.setReconnectThresholdTime(time, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view timeout in miliseconds.
|
||||
*
|
||||
* @param timeout the view timeout.
|
||||
*/
|
||||
public void setViewTimeout(final int timeout) {
|
||||
builder.setViewTimeout(timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the failure mode if memcached buckets are used.
|
||||
*
|
||||
* See the proper values of {@link FailureMode} to use.
|
||||
*
|
||||
* @param mode the failure mode.
|
||||
*/
|
||||
public void setFailureMode(final String mode) {
|
||||
builder.setFailureMode(FailureMode.valueOf(mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the operation timeout in miliseconds.
|
||||
*
|
||||
* @param timeout the operation timeout.
|
||||
*/
|
||||
public void setOpTimeout(final int timeout) {
|
||||
builder.setOpTimeout(timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the operation queue maximum block time in miliseconds.
|
||||
*
|
||||
* @param time the operation queue maximum block time.
|
||||
*/
|
||||
public void setOpQueueMaxBlockTime(final int time) {
|
||||
builder.setOpQueueMaxBlockTime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the client when the bean is destroyed.
|
||||
*
|
||||
* @throws Exception if shutdown failed.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
couchbaseClient.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying {@link CouchbaseClient}.
|
||||
*
|
||||
* @return the client object.
|
||||
* @throws Exception if returning the client failed.
|
||||
*/
|
||||
@Override
|
||||
public CouchbaseClient getObject() throws Exception {
|
||||
return couchbaseClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object type of the client.
|
||||
*
|
||||
* @return the {@link CouchbaseClient} class.
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return CouchbaseClient.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The client should be returned as a singleton.
|
||||
*
|
||||
* @return returns true.
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nodes as an array of URIs.
|
||||
*
|
||||
* @param nodes the nodes to connect to.
|
||||
*/
|
||||
public void setNodes(final URI[] nodes) {
|
||||
this.nodes = filterNonNullElementsAsList(nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the array of elements to a list and filter empty or null elements.
|
||||
*
|
||||
* @param elements the elements to convert.
|
||||
* @param <T> the type of the elements.
|
||||
* @return the converted list.
|
||||
*/
|
||||
private <T> List<T> filterNonNullElementsAsList(T[] elements) {
|
||||
if (elements == null) {
|
||||
return Collections.emptyList();
|
||||
@@ -119,6 +226,11 @@ public class CouchbaseFactoryBean implements FactoryBean<CouchbaseClient>, Initi
|
||||
return Collections.unmodifiableList(candidateElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the {@link CouchbaseClient}.
|
||||
*
|
||||
* @throws Exception if something goes wrong during instantiation.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
nodes = nodes != null ? nodes : Arrays.asList(new URI("http://" + DEFAULT_NODE + ":8091/pools"));
|
||||
@@ -129,8 +241,15 @@ public class CouchbaseFactoryBean implements FactoryBean<CouchbaseClient>, Initi
|
||||
couchbaseClient = new CouchbaseClient(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate exception if possible.
|
||||
*
|
||||
* @param ex the exception to translate.
|
||||
* @return the translate exception.
|
||||
*/
|
||||
@Override
|
||||
public DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
|
||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import com.couchbase.client.protocol.views.ViewResponse;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
|
||||
/**
|
||||
* Defines common operations on the Couchbase data source, most commonly implemented by {@link CouchbaseTemplate}.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseOperations {
|
||||
@@ -32,13 +34,8 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Save the given object.
|
||||
*
|
||||
* When the document already exists (specified by its unique id),
|
||||
* then it will be overriden. Otherwise it will be created.
|
||||
*
|
||||
* <p>
|
||||
* The object is converted to a JSON representation using an instance of
|
||||
* {@link CouchbaseConverter}.
|
||||
* </p>
|
||||
* <p>When the document already exists (specified by its unique id), then it will be overriden. Otherwise it will be
|
||||
* created.</p>
|
||||
*
|
||||
* @param objectToSave the object to store in the bucket.
|
||||
*/
|
||||
@@ -47,8 +44,8 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Save a list of objects.
|
||||
*
|
||||
* When one of the documents already exists (specified by its unique id),
|
||||
* then it will be overriden. Otherwise it will be created.
|
||||
* <p>When one of the documents already exists (specified by its unique id), then it will be overriden. Otherwise it
|
||||
* will be created.</p>
|
||||
*
|
||||
* @param batchToSave the list of objects to store in the bucket.
|
||||
*/
|
||||
@@ -57,14 +54,8 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Insert the given object.
|
||||
*
|
||||
* When the document already exists (specified by its unique id),
|
||||
* then it will not be overriden. Use the {@link CouchbaseOperations#save}
|
||||
* method for this.
|
||||
*
|
||||
* <p>
|
||||
* The object is converted to a JSON representation using an instance of
|
||||
* {@link CouchbaseConverter}.
|
||||
* </p>
|
||||
* <p>When the document already exists (specified by its unique id), then it will not be overriden. Use the
|
||||
* {@link CouchbaseOperations#save} method for this task.</p>
|
||||
*
|
||||
* @param objectToSave the object to add to the bucket.
|
||||
*/
|
||||
@@ -73,9 +64,8 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Insert a list of objects.
|
||||
*
|
||||
* When one of the documents already exists (specified by its unique id),
|
||||
* then it will not be overriden. Use the {@link CouchbaseOperations#save}
|
||||
* method for this.
|
||||
* <p>When one of the documents already exists (specified by its unique id), then it will not be overriden. Use the
|
||||
* {@link CouchbaseOperations#save} method for this.</p>
|
||||
*
|
||||
* @param batchToSave the list of objects to add to the bucket.
|
||||
*/
|
||||
@@ -84,14 +74,8 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Update the given object.
|
||||
*
|
||||
* When the document does not exists (specified by its unique id),
|
||||
* then it will not be created. Use the {@link CouchbaseOperations#save}
|
||||
* method for this.
|
||||
*
|
||||
* <p>
|
||||
* The object is converted to a JSON representation using an instance of
|
||||
* {@link CouchbaseConverter}.
|
||||
* </p>
|
||||
* <p>When the document does not exist (specified by its unique id) it will not be created. Use the
|
||||
* {@link CouchbaseOperations#save} method for this.</p>
|
||||
*
|
||||
* @param objectToSave the object to add to the bucket.
|
||||
*/
|
||||
@@ -100,9 +84,8 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Insert a list of objects.
|
||||
*
|
||||
* When one of the documents does not exists (specified by its unique id),
|
||||
* then it will not be created. Use the {@link CouchbaseOperations#save}
|
||||
* method for this.
|
||||
* <p>If one of the documents does not exist (specified by its unique id), then it will not be created. Use the
|
||||
* {@link CouchbaseOperations#save} method for this.</p>
|
||||
*
|
||||
* @param batchToSave the list of objects to add to the bucket.
|
||||
*/
|
||||
@@ -120,13 +103,11 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Query a View for a list of documents of type T.
|
||||
*
|
||||
* <p>There is no need to {@link Query#setIncludeDocs(boolean)} explicitely,
|
||||
* because it will be set to true all the time. It is valid to pass in a
|
||||
* empty constructed {@link Query} object.</p>
|
||||
* <p>There is no need to {@link Query#setIncludeDocs(boolean)} explicitely, because it will be set to true all the
|
||||
* time. It is valid to pass in a empty constructed {@link Query} object.</p>
|
||||
*
|
||||
* <p>This method does not work with reduced views, because they by design
|
||||
* do not contain references to original objects. Use the provided
|
||||
* {@link #queryView} method for more flexibility and direct access.</p>
|
||||
* <p>This method does not work with reduced views, because they by design do not contain references to original
|
||||
* objects. Use the provided {@link #queryView} method for more flexibility and direct access.</p>
|
||||
*
|
||||
* @param design the name of the design document.
|
||||
* @param view the name of the view.
|
||||
@@ -140,11 +121,11 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Query a View with direct access to the {@link ViewResponse}.
|
||||
*
|
||||
* <p>This method is available to ease the working with views by still wrapping
|
||||
* exceptions into the Spring infrastructure.</p>
|
||||
* <p>This method is available to ease the working with views by still wrapping exceptions into the Spring
|
||||
* infrastructure.</p>
|
||||
*
|
||||
* <p>It is especially needed if you want to run reduced view queries, because
|
||||
* they can't be mapped onto entities directly.</p>
|
||||
* <p>It is especially needed if you want to run reduced view queries, because they can't be mapped onto entities
|
||||
* directly.</p>
|
||||
*
|
||||
* @param design the name of the design document.
|
||||
* @param view the name of the view.
|
||||
@@ -181,8 +162,7 @@ public interface CouchbaseOperations {
|
||||
/**
|
||||
* Executes a BucketCallback translating any exceptions as necessary.
|
||||
*
|
||||
* Allows for returning a result object, that is a domain object or a
|
||||
* collection of domain objects.
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param action the action to execute in the callback.
|
||||
* @param <T> the return type.
|
||||
@@ -191,7 +171,7 @@ public interface CouchbaseOperations {
|
||||
<T> T execute(BucketCallback<T> action);
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link CouchbaseConverter}
|
||||
* Returns the underlying {@link CouchbaseConverter}.
|
||||
* @return
|
||||
*/
|
||||
CouchbaseConverter getConverter();
|
||||
|
||||
@@ -31,10 +31,7 @@ import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
|
||||
import org.springframework.data.couchbase.core.convert.translation.TranslationService;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
|
||||
import org.springframework.data.couchbase.core.mapping.*;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
|
||||
import com.couchbase.client.CouchbaseClient;
|
||||
|
||||
@@ -19,8 +19,7 @@ package org.springframework.data.couchbase.core;
|
||||
import org.springframework.dao.TransientDataAccessException;
|
||||
|
||||
/**
|
||||
* Data Access Exception that identifies Operations cancelled while being
|
||||
* processed.
|
||||
* Data Access Exception that identifies Operations cancelled while being processed.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
|
||||
@@ -19,8 +19,7 @@ package org.springframework.data.couchbase.core;
|
||||
import org.springframework.dao.TransientDataAccessException;
|
||||
|
||||
/**
|
||||
* Data Access Exception that identifies Operations interrupted while being
|
||||
* processed.
|
||||
* Data Access Exception that identifies Operations interrupted while being processed.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
|
||||
@@ -22,27 +22,50 @@ import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.EntityInstantiators;
|
||||
|
||||
/**
|
||||
* An abstract {@link CouchbaseConverter} that provides the basics for the {@link MappingCouchbaseConverter}.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public abstract class AbstractCouchbaseConverter implements CouchbaseConverter,
|
||||
InitializingBean {
|
||||
public abstract class AbstractCouchbaseConverter implements CouchbaseConverter, InitializingBean {
|
||||
|
||||
/**
|
||||
* Contains the conversion service.
|
||||
*/
|
||||
protected final GenericConversionService conversionService;
|
||||
|
||||
/**
|
||||
* Contains the entity instantiators.
|
||||
*/
|
||||
protected EntityInstantiators instantiators = new EntityInstantiators();
|
||||
|
||||
/**
|
||||
* Holds the custom conversions.
|
||||
*/
|
||||
protected CustomConversions conversions = new CustomConversions();
|
||||
|
||||
public AbstractCouchbaseConverter(
|
||||
GenericConversionService conversionService) {
|
||||
/**
|
||||
* Create a new converter and hand it over the {@link ConversionService}
|
||||
*
|
||||
* @param conversionService the conversion service to use.
|
||||
*/
|
||||
public AbstractCouchbaseConverter(final GenericConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the conversion service.
|
||||
*
|
||||
* @return the conversion service.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing after the properties set on the bean.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,11 +23,13 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
|
||||
/**
|
||||
* Marker interface for the converter, identifying the types to and from that can be converted.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseConverter extends
|
||||
EntityConverter<CouchbasePersistentEntity<?>,
|
||||
CouchbasePersistentProperty, Object, CouchbaseDocument>,
|
||||
public interface CouchbaseConverter
|
||||
extends EntityConverter<CouchbasePersistentEntity<?>,
|
||||
CouchbasePersistentProperty, Object, CouchbaseDocument>,
|
||||
CouchbaseWriter<Object, CouchbaseDocument>,
|
||||
EntityReader<Object, CouchbaseDocument> {
|
||||
}
|
||||
|
||||
@@ -24,24 +24,50 @@ import org.springframework.expression.TypedValue;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A property accessor for document properties.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseDocumentPropertyAccessor extends MapAccessor {
|
||||
|
||||
static MapAccessor INSTANCE = new CouchbaseDocumentPropertyAccessor();
|
||||
/**
|
||||
* Contains the static instance of thi accessor.
|
||||
*/
|
||||
static final MapAccessor INSTANCE = new CouchbaseDocumentPropertyAccessor();
|
||||
|
||||
/**
|
||||
* Returns the target classes of the properties.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] {CouchbaseDocument.class};
|
||||
}
|
||||
|
||||
/**
|
||||
* It can always read from those properties.
|
||||
*
|
||||
* @param context the evaluation context.
|
||||
* @param target the target object.
|
||||
* @param name the name of the property.
|
||||
* @return always true.
|
||||
*/
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) {
|
||||
public boolean canRead(final EvaluationContext context, final Object target, final String name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value from the property.
|
||||
*
|
||||
* @param context the evaluation context.
|
||||
* @param target the target object.
|
||||
* @param name the name of the property.
|
||||
* @return the typed value of the content to be read.
|
||||
*/
|
||||
@Override
|
||||
public TypedValue read(EvaluationContext contect, Object target, String name) {
|
||||
public TypedValue read(final EvaluationContext context, final Object target, final String name) {
|
||||
Map<String, Object> source = (Map<String, Object>) target;
|
||||
|
||||
Object value = source.get(name);
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* Marker interface for the TypeMapper.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseTypeMapper extends TypeMapper<CouchbaseDocument> {
|
||||
|
||||
@@ -19,9 +19,10 @@ package org.springframework.data.couchbase.core.convert;
|
||||
import org.springframework.data.convert.EntityWriter;
|
||||
|
||||
/**
|
||||
* Marker interface for the Couchbase {@link EntityWriter}.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseWriter<T, ConvertedCouchbaseDocument> extends
|
||||
EntityWriter<T, ConvertedCouchbaseDocument> {
|
||||
|
||||
}
|
||||
@@ -27,26 +27,42 @@ import java.util.Set;
|
||||
/**
|
||||
* Value object to capture custom conversion.
|
||||
*
|
||||
* Types that can be mapped directly onto JSON are considered simple ones,
|
||||
* because they neither need deeper inspection nor nested conversion.
|
||||
* <p>Types that can be mapped directly onto JSON are considered simple ones, because they neither need deeper
|
||||
* inspection nor nested conversion.</p>
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CustomConversions {
|
||||
|
||||
/**
|
||||
* Contains the simple type holder.
|
||||
*/
|
||||
private final SimpleTypeHolder simpleTypeHolder;
|
||||
|
||||
/**
|
||||
* Create a new instance with no converters.
|
||||
*/
|
||||
CustomConversions() {
|
||||
this(new ArrayList<Object>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with a given list of conversers.
|
||||
* @param converters the list of custom converters.
|
||||
*/
|
||||
public CustomConversions(final List<?> converters) {
|
||||
Assert.notNull(converters);
|
||||
|
||||
simpleTypeHolder = new SimpleTypeHolder();
|
||||
}
|
||||
|
||||
public boolean isSimpleType(Class<?> type) {
|
||||
/**
|
||||
* Check that the given type is of "simple type".
|
||||
*
|
||||
* @param type the type to check.
|
||||
* @return if its simple type or not.
|
||||
*/
|
||||
public boolean isSimpleType(final Class<?> type) {
|
||||
return simpleTypeHolder.isSimpleType(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,22 @@ import org.springframework.data.convert.TypeAliasAccessor;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
|
||||
/**
|
||||
* The Couchbase Type Mapper.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class DefaultCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocument> implements CouchbaseTypeMapper {
|
||||
|
||||
/**
|
||||
* The type key to use if a complex type was identified.
|
||||
*/
|
||||
public static final String DEFAULT_TYPE_KEY = "_class";
|
||||
|
||||
/**
|
||||
* Create a new type mapper with the type key.
|
||||
*
|
||||
* @param typeKey the typeKey to use.
|
||||
*/
|
||||
public DefaultCouchbaseTypeMapper(final String typeKey) {
|
||||
super(new CouchbaseDocumentTypeAliasAccessor(typeKey));
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.data.couchbase.core.convert;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -39,6 +38,10 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* The Couchbase special {@link MappingCouchbaseConverter}.
|
||||
*
|
||||
* This converter is responsible for mapping (read and writing) value from and to target formats.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
|
||||
|
||||
@@ -27,19 +27,31 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A Jackson JSON Translator.
|
||||
* A Jackson JSON Translator that implements the {@link TranslationService} contract.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class JacksonTranslationService implements TranslationService {
|
||||
|
||||
/**
|
||||
* Type holder to help easily identify simple types.
|
||||
*/
|
||||
private SimpleTypeHolder simpleTypeHolder = new SimpleTypeHolder();
|
||||
|
||||
/**
|
||||
* JSON factory for Jackson.
|
||||
*/
|
||||
private JsonFactory factory = new JsonFactory();
|
||||
|
||||
/**
|
||||
* Encode a {@link CouchbaseStorable} to a JSON string.
|
||||
*
|
||||
* @param source the source document to encode.
|
||||
* @return the encoded JSON String.
|
||||
*/
|
||||
@Override
|
||||
public final Object encode(final CouchbaseStorable source) {
|
||||
OutputStream stream = new ByteArrayOutputStream();
|
||||
@@ -86,6 +98,13 @@ public class JacksonTranslationService implements TranslationService {
|
||||
generator.writeEndObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a JSON string into the {@link CouchbaseStorable} structure.
|
||||
*
|
||||
* @param source the source formatted document.
|
||||
* @param target the target of the populated data.
|
||||
* @return the decoded structure.
|
||||
*/
|
||||
@Override
|
||||
public final CouchbaseStorable decode(final Object source, final CouchbaseStorable target) {
|
||||
try {
|
||||
@@ -108,6 +127,14 @@ public class JacksonTranslationService implements TranslationService {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to decode an object recursively.
|
||||
*
|
||||
* @param parser the JSON parser with the content.
|
||||
* @param target the target where the content should be stored.
|
||||
* @returns the decoded object.
|
||||
* @throws IOException
|
||||
*/
|
||||
private CouchbaseDocument decodeObject(final JsonParser parser, final CouchbaseDocument target) throws IOException {
|
||||
JsonToken currentToken = parser.nextToken();
|
||||
|
||||
@@ -129,6 +156,14 @@ public class JacksonTranslationService implements TranslationService {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to decode an array recusrively.
|
||||
*
|
||||
* @param parser the JSON parser with the content.
|
||||
* @param target the target where the content should be stored.
|
||||
* @returns the decoded list.
|
||||
* @throws IOException
|
||||
*/
|
||||
private CouchbaseList decodeArray(final JsonParser parser, final CouchbaseList target) throws IOException {
|
||||
JsonToken currentToken = parser.nextToken();
|
||||
|
||||
@@ -147,6 +182,14 @@ public class JacksonTranslationService implements TranslationService {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to decode and assign a primitive.
|
||||
*
|
||||
* @param token the type of token.
|
||||
* @param parser the parser with the content.
|
||||
* @return the decoded primitve.
|
||||
* @throws IOException
|
||||
*/
|
||||
private Object decodePrimitive(final JsonToken token, final JsonParser parser) throws IOException {
|
||||
switch (token) {
|
||||
case VALUE_TRUE:
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.springframework.data.couchbase.core.mapping.CouchbaseDocument;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseStorable;
|
||||
|
||||
/**
|
||||
* Defines a translation service to encode/decode responses into the {@link CouchbaseStorable} format.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface TranslationService<T> {
|
||||
|
||||
@@ -26,36 +26,49 @@ import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* The representation of a persistent entity.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class BasicCouchbasePersistentEntity<T>
|
||||
extends BasicPersistentEntity<T, CouchbasePersistentProperty>
|
||||
public class BasicCouchbasePersistentEntity<T> extends BasicPersistentEntity<T, CouchbasePersistentProperty>
|
||||
implements CouchbasePersistentEntity<T>, ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Contains the evaluation context.
|
||||
*/
|
||||
private final StandardEvaluationContext context;
|
||||
|
||||
public BasicCouchbasePersistentEntity(TypeInformation<T> typeInformation) {
|
||||
/**
|
||||
* Create a new entity.
|
||||
* @param typeInformation the type information of the entity.
|
||||
*/
|
||||
public BasicCouchbasePersistentEntity(final TypeInformation<T> typeInformation) {
|
||||
super(typeInformation);
|
||||
|
||||
this.context = new StandardEvaluationContext();
|
||||
context = new StandardEvaluationContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application context.
|
||||
*
|
||||
* @param applicationContext the application context.
|
||||
* @throws BeansException if setting the application context did go wrong.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
|
||||
context.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
context.setRootObject(applicationContext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the expiration time of the entity.
|
||||
*
|
||||
* @return the expiration time.
|
||||
*/
|
||||
public int getExpiry() {
|
||||
org.springframework.data.couchbase.core.mapping.Document annotation =
|
||||
getType().getAnnotation(org.springframework.data.couchbase.core.mapping.Document.class);
|
||||
|
||||
if(annotation == null) {
|
||||
return 0;
|
||||
}
|
||||
return annotation.expiry();
|
||||
return annotation == null ? 0 : annotation.expiry();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,9 +26,8 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* Implements annotated property representations of a given Field instance.
|
||||
*
|
||||
* This object is used to gather information out of properties on objects
|
||||
* that need to be persisted. For example, it supports overriding of the
|
||||
* actual property name by providing custom annotations.
|
||||
* <p>This object is used to gather information out of properties on objects that need to be persisted. For example, it
|
||||
* supports overriding of the actual property name by providing custom annotations.</p>
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@@ -44,9 +43,8 @@ public class BasicCouchbasePersistentProperty
|
||||
* @param owner the original owner of the property.
|
||||
* @param simpleTypeHolder the type holder.
|
||||
*/
|
||||
public BasicCouchbasePersistentProperty(Field field,
|
||||
PropertyDescriptor propertyDescriptor, CouchbasePersistentEntity<?> owner,
|
||||
SimpleTypeHolder simpleTypeHolder) {
|
||||
public BasicCouchbasePersistentProperty(final Field field, final PropertyDescriptor propertyDescriptor,
|
||||
final CouchbasePersistentEntity<?> owner, final SimpleTypeHolder simpleTypeHolder) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,19 +24,15 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A {@link CouchbaseDocument} is an abstract representation of a document stored
|
||||
* inside Couchbase Server.
|
||||
* A {@link CouchbaseDocument} is an abstract representation of a document stored inside Couchbase Server.
|
||||
*
|
||||
* <p>It acts like a {@link HashMap}, but only allows those types to be written
|
||||
* that are supported by the underlying storage format, which is currently
|
||||
* JSON. Note that JSON conversion is not happening here, but performed
|
||||
* at a different stage based on the payload stored in the
|
||||
* {@link CouchbaseDocument}.</p>
|
||||
* <p>It acts like a {@link HashMap}, but only allows those types to be written that are supported by the underlying
|
||||
* storage format, which is currently JSON. Note that JSON conversion is not happening here, but performed at a
|
||||
* different stage based on the payload stored in the {@link CouchbaseDocument}.</p>
|
||||
*
|
||||
* <p>In addition to the actual content, meta data is also stored. This
|
||||
* especially refers to the document ID and its expiration time. Note that
|
||||
* this information is not mandatory, since documents can be nested and
|
||||
* therefore only the topmost document most likely has an ID.</p>
|
||||
* <p>In addition to the actual content, meta data is also stored. This especially refers to the document ID and its
|
||||
* expiration time. Note that this information is not mandatory, since documents can be nested and therefore only the
|
||||
* topmost document most likely has an ID.</p>
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
@@ -199,6 +195,13 @@ public class CouchbaseDocument implements CouchbaseStorable {
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying payload.
|
||||
*
|
||||
* <p>Note that unlike {@link #export()}, the nested objects are not converted, so the "raw" map is returned.</p>
|
||||
*
|
||||
* @return the underlying payload.
|
||||
*/
|
||||
public HashMap<String, Object> getPayload() {
|
||||
return payload;
|
||||
}
|
||||
@@ -267,6 +270,11 @@ public class CouchbaseDocument implements CouchbaseStorable {
|
||||
+ clazz.getCanonicalName() + " can not be stored and must be converted.");
|
||||
}
|
||||
|
||||
/**
|
||||
* A string representation of expiration, id and payload.
|
||||
*
|
||||
* @return the string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CouchbaseDocument{" +
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* 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.couchbase.core.mapping;
|
||||
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
@@ -5,12 +21,10 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A {@link CouchbaseList} is an abstract list that represents an array stored
|
||||
* in a (most of the times JSON) document.
|
||||
* A {@link CouchbaseList} is an abstract list that represents an array stored in a (most of the times JSON) document.
|
||||
*
|
||||
* This {@link CouchbaseList} is part of the potentially nested structure inside
|
||||
* one or more {@link CouchbaseDocument}s. It can also contain them recursively,
|
||||
* depending on how the document is modeled.
|
||||
* <p>This {@link CouchbaseList} is part of the potentially nested structure inside one or more
|
||||
* {@link CouchbaseDocument}s. It can also contain them recursively, depending on how the document is modeled.</p>
|
||||
*/
|
||||
public class CouchbaseList implements CouchbaseStorable {
|
||||
|
||||
@@ -24,11 +38,19 @@ public class CouchbaseList implements CouchbaseStorable {
|
||||
*/
|
||||
private SimpleTypeHolder simpleTypeHolder;
|
||||
|
||||
/**
|
||||
* Create a new (empty) list.
|
||||
*/
|
||||
public CouchbaseList() {
|
||||
this(new ArrayList<Object>());
|
||||
}
|
||||
|
||||
public CouchbaseList(List<Object> initialPayload) {
|
||||
/**
|
||||
* Create a new list with a given payload on construction.
|
||||
*
|
||||
* @param initialPayload the initial data to store.
|
||||
*/
|
||||
public CouchbaseList(final List<Object> initialPayload) {
|
||||
payload = initialPayload;
|
||||
|
||||
Set<Class<?>> additionalTypes = new HashSet<Class<?>>();
|
||||
@@ -37,14 +59,26 @@ public class CouchbaseList implements CouchbaseStorable {
|
||||
simpleTypeHolder = new SimpleTypeHolder(additionalTypes, true);
|
||||
}
|
||||
|
||||
public final CouchbaseList put(Object value) {
|
||||
/**
|
||||
* Add content to the underlying list.
|
||||
*
|
||||
* @param value the value to be added.
|
||||
* @return the {@link CouchbaseList} object for chaining purposes.
|
||||
*/
|
||||
public final CouchbaseList put(final Object value) {
|
||||
verifyValueType(value.getClass());
|
||||
|
||||
payload.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Object get(int index) {
|
||||
/**
|
||||
* Return the stored element at the given index.
|
||||
*
|
||||
* @param index the index where the document is located.
|
||||
* @return the found object (or null if nothing found).
|
||||
*/
|
||||
public final Object get(final int index) {
|
||||
return payload.get(index);
|
||||
}
|
||||
|
||||
@@ -117,6 +151,11 @@ public class CouchbaseList implements CouchbaseStorable {
|
||||
return payload.contains(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the underlying payload is empty or not.
|
||||
*
|
||||
* @return whether the underlying payload is empty or not.
|
||||
*/
|
||||
public final boolean isEmpty() {
|
||||
return payload.isEmpty();
|
||||
}
|
||||
@@ -139,6 +178,11 @@ public class CouchbaseList implements CouchbaseStorable {
|
||||
+ clazz.getCanonicalName() + "can not be stored and must be converted.");
|
||||
}
|
||||
|
||||
/**
|
||||
* A string reprensation of the payload.
|
||||
*
|
||||
* @return the underlying payload as a string representation for easier debugging.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CouchbaseList{" +
|
||||
|
||||
@@ -14,47 +14,72 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.couchbase.core;
|
||||
package org.springframework.data.couchbase.core.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.couchbase.core.mapping.BasicCouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.BasicCouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link org.springframework.data.mapping.context.MappingContext} for Couchbase using
|
||||
* {@link BasicCouchbasePersistentEntity} and {@link BasicCouchbasePersistentProperty} as primary abstractions.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseMappingContext
|
||||
extends AbstractMappingContext<BasicCouchbasePersistentEntity<?>, CouchbasePersistentProperty>
|
||||
implements ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Contains the application context to configure the application.
|
||||
*/
|
||||
private ApplicationContext context;
|
||||
|
||||
/**
|
||||
* Creates a concrete entity based out of the type information passed.
|
||||
*
|
||||
* @param typeInformation type information of the entity to create.
|
||||
* @param <T> the type for the corresponding type information.
|
||||
* @return the constructed entity.
|
||||
*/
|
||||
@Override
|
||||
protected <T> BasicCouchbasePersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
protected <T> BasicCouchbasePersistentEntity<?> createPersistentEntity(final TypeInformation<T> typeInformation) {
|
||||
BasicCouchbasePersistentEntity<T> entity = new BasicCouchbasePersistentEntity<T>(typeInformation);
|
||||
if(context != null) {
|
||||
if (context != null) {
|
||||
entity.setApplicationContext(context);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a concrete property based on the field information and entity.
|
||||
*
|
||||
* @param field the reflection on the field to be used as a property.
|
||||
* @param descriptor the property descriptor.
|
||||
* @param owner the entity which owns the property.
|
||||
* @param simpleTypeHolder the type holder.
|
||||
* @return the constructed property.
|
||||
*/
|
||||
@Override
|
||||
protected CouchbasePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, BasicCouchbasePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
protected CouchbasePersistentProperty createPersistentProperty(final Field field, final PropertyDescriptor descriptor,
|
||||
final BasicCouchbasePersistentEntity<?> owner, final SimpleTypeHolder simpleTypeHolder) {
|
||||
return new BasicCouchbasePersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (or overrides) the current application context.
|
||||
*
|
||||
* @param applicationContext the application context to be assigned.
|
||||
* @throws BeansException if the context can not be set properly.
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.context = applicationContext;
|
||||
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
|
||||
context = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,15 +19,18 @@ package org.springframework.data.couchbase.core.mapping;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
|
||||
/**
|
||||
* Represents an entity that can be persisted which contains 0 or more properties.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbasePersistentEntity<T> extends
|
||||
PersistentEntity<T, CouchbasePersistentProperty> {
|
||||
|
||||
/**
|
||||
* Returns the expiry time for the document.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/**
|
||||
* Returns the expiry time for the document.
|
||||
*
|
||||
* @return the expiration time.
|
||||
*/
|
||||
int getExpiry();
|
||||
|
||||
}
|
||||
|
||||
@@ -19,16 +19,16 @@ package org.springframework.data.couchbase.core.mapping;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
|
||||
/**
|
||||
* Represents a property part of an entity that needs to be persisted.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbasePersistentProperty extends
|
||||
PersistentProperty<CouchbasePersistentProperty> {
|
||||
public interface CouchbasePersistentProperty extends PersistentProperty<CouchbasePersistentProperty> {
|
||||
|
||||
/**
|
||||
* Returns the field name of the property.
|
||||
*
|
||||
* The field name can be different from the actual property name by using a
|
||||
* custom annotation.
|
||||
* The field name can be different from the actual property name by using a custom annotation.
|
||||
*/
|
||||
String getFieldName();
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package org.springframework.data.couchbase.core.mapping;
|
||||
|
||||
/**
|
||||
* Marker Interface to identify either a {@link CouchbaseDocument} or a {@link CouchbaseList}.
|
||||
*
|
||||
* This interface will be extended in the future to refactor the needed infrastructure into the common interface.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseStorable {
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ import org.springframework.data.repository.CrudRepository;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Couchbase specific {@link org.springframework.data.repository.Repository}
|
||||
* interface.
|
||||
* Couchbase specific {@link org.springframework.data.repository.Repository} interface.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
|
||||
@@ -42,13 +42,13 @@ public class CouchbaseRepositoryConfigurationExtension extends RepositoryConfigu
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(BeanDefinitionBuilder builder, XmlRepositoryConfigurationSource config) {
|
||||
public void postProcess(final BeanDefinitionBuilder builder, final XmlRepositoryConfigurationSource config) {
|
||||
Element element = config.getElement();
|
||||
ParsingUtils.setPropertyReference(builder, element, COUCHBASE_TEMPLATE_REF, "couchbaseOperations");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource config) {
|
||||
public void postProcess(final BeanDefinitionBuilder builder, final AnnotationRepositoryConfigurationSource config) {
|
||||
AnnotationAttributes attributes = config.getAttributes();
|
||||
builder.addPropertyReference("couchbaseOperations", attributes.getString("couchbaseTemplateRef"));
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.springframework.data.repository.core.EntityInformation;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Marker interface for the Couchbase Entity Information.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public interface CouchbaseEntityInformation<T, ID extends Serializable> extends EntityInformation<T, ID> {
|
||||
|
||||
@@ -29,43 +29,75 @@ import org.springframework.util.Assert;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Factory to create {@link CouchbaseRepository} instances.
|
||||
* Factory to create {@link SimpleCouchbaseRepository} instances.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
/**
|
||||
* Holds the reference to the template.
|
||||
*/
|
||||
private final CouchbaseOperations couchbaseOperations;
|
||||
private final MappingContext<? extends CouchbasePersistentEntity<?>,
|
||||
CouchbasePersistentProperty> mappingContext;
|
||||
|
||||
/**
|
||||
* Holds the mapping context.
|
||||
*/
|
||||
private final MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;
|
||||
|
||||
/**
|
||||
* Create a new factory.
|
||||
*
|
||||
* @param couchbaseOperations the template for the underlying actions.
|
||||
*/
|
||||
public CouchbaseRepositoryFactory(final CouchbaseOperations couchbaseOperations) {
|
||||
Assert.notNull(couchbaseOperations);
|
||||
|
||||
this.couchbaseOperations = couchbaseOperations;
|
||||
mappingContext = couchbaseOperations.getConverter().getMappingContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns entity information based on the domain class.
|
||||
*
|
||||
* @param domainClass the class for the entity.
|
||||
* @param <T> the value type
|
||||
* @param <ID> the id type.
|
||||
* @return entity information for that domain class.
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable> CouchbaseEntityInformation<T, ID>
|
||||
getEntityInformation(Class<T> domainClass) {
|
||||
getEntityInformation(final Class<T> domainClass) {
|
||||
CouchbasePersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
|
||||
|
||||
if(entity == null) {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Repository based on the metadata.
|
||||
*
|
||||
* @param metadata the repository metadata.
|
||||
* @return a new created repository.
|
||||
*/
|
||||
@Override
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
protected Object getTargetRepository(final RepositoryMetadata metadata) {
|
||||
CouchbaseEntityInformation<?, Serializable> entityInformation =
|
||||
getEntityInformation(metadata.getDomainType());
|
||||
return new SimpleCouchbaseRepository(entityInformation, couchbaseOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* The base class for this repository.
|
||||
*
|
||||
* @param repositoryMetadata metadata for the repository.
|
||||
* @return the base class.
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getRepositoryBaseClass(RepositoryMetadata repositoryMetadata) {
|
||||
protected Class<?> getRepositoryBaseClass(final RepositoryMetadata repositoryMetadata) {
|
||||
return SimpleCouchbaseRepository.class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,27 +25,51 @@ import org.springframework.util.Assert;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The factory bean to create repositories.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class CouchbaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
|
||||
RepositoryFactoryBeanSupport<T, S, ID> {
|
||||
|
||||
/**
|
||||
* Contains the reference to the template.
|
||||
*/
|
||||
private CouchbaseOperations operations;
|
||||
|
||||
public void setCouchbaseOperations(CouchbaseOperations operations) {
|
||||
/**
|
||||
* Set the template reference.
|
||||
*
|
||||
* @param operations the reference to the operations template.
|
||||
*/
|
||||
public void setCouchbaseOperations(final CouchbaseOperations operations) {
|
||||
this.operations = operations;
|
||||
setMappingContext(operations.getConverter().getMappingContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a factory instance.
|
||||
*
|
||||
* @return the factory instance.
|
||||
*/
|
||||
@Override
|
||||
protected RepositoryFactorySupport createRepositoryFactory() {
|
||||
return getFactoryInstance(operations);
|
||||
}
|
||||
|
||||
private RepositoryFactorySupport getFactoryInstance(CouchbaseOperations operations) {
|
||||
/**
|
||||
* Get the factory instance for the operations.
|
||||
*
|
||||
* @param operations the reference to the template.
|
||||
* @return the factory instance.
|
||||
*/
|
||||
private RepositoryFactorySupport getFactoryInstance(final CouchbaseOperations operations) {
|
||||
return new CouchbaseRepositoryFactory(operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the template is set and not null.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
|
||||
@@ -25,24 +25,40 @@ import org.springframework.data.repository.core.support.AbstractEntityInformatio
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Entity Information container.
|
||||
*
|
||||
* @author Michael Nitschinger
|
||||
*/
|
||||
public class MappingCouchbaseEntityInformation<T, ID extends Serializable>
|
||||
extends AbstractEntityInformation<T, ID>
|
||||
implements CouchbaseEntityInformation<T, ID> {
|
||||
|
||||
/**
|
||||
* Contains the entity metadata.
|
||||
*/
|
||||
private final CouchbasePersistentEntity<T> entityMetadata;
|
||||
|
||||
public MappingCouchbaseEntityInformation(CouchbasePersistentEntity<T> entity) {
|
||||
/**
|
||||
* Create a new Infomration container.
|
||||
*
|
||||
* @param entity the entity of the container.
|
||||
*/
|
||||
public MappingCouchbaseEntityInformation(final CouchbasePersistentEntity<T> entity) {
|
||||
super(entity.getType());
|
||||
entityMetadata = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the entity.
|
||||
*
|
||||
* @param entity the entity from where to extract the ID from.
|
||||
* @return the id of the entity.
|
||||
*/
|
||||
@Override
|
||||
public ID getId(T entity) {
|
||||
CouchbasePersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
|
||||
if(idProperty == null) {
|
||||
if (idProperty == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -53,6 +69,11 @@ public class MappingCouchbaseEntityInformation<T, ID extends Serializable>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID type.
|
||||
*
|
||||
* @return the ID type.
|
||||
*/
|
||||
@Override
|
||||
public Class<ID> getIdType() {
|
||||
return (Class<ID>) entityMetadata.getIdProperty().getType();
|
||||
|
||||
@@ -39,11 +39,25 @@ import java.util.List;
|
||||
*/
|
||||
public class SimpleCouchbaseRepository<T, ID extends Serializable> implements CouchbaseRepository<T, ID> {
|
||||
|
||||
/**
|
||||
* Holds the reference to the {@link org.springframework.data.couchbase.core.CouchbaseTemplate}.
|
||||
*/
|
||||
private final CouchbaseOperations couchbaseOperations;
|
||||
|
||||
/**
|
||||
* Contains information about the entity being used in this repository.
|
||||
*/
|
||||
private final CouchbaseEntityInformation<T, String> entityInformation;
|
||||
|
||||
|
||||
public SimpleCouchbaseRepository(CouchbaseEntityInformation<T, String> metadata, CouchbaseOperations couchbaseOperations) {
|
||||
/**
|
||||
* Create a new Repository.
|
||||
*
|
||||
* @param metadata the Metadata for the entity.
|
||||
* @param couchbaseOperations the reference to the template used.
|
||||
*/
|
||||
public SimpleCouchbaseRepository(final CouchbaseEntityInformation<T, String> metadata,
|
||||
final CouchbaseOperations couchbaseOperations) {
|
||||
Assert.notNull(couchbaseOperations);
|
||||
Assert.notNull(metadata);
|
||||
|
||||
@@ -156,10 +170,20 @@ public class SimpleCouchbaseRepository<T, ID extends Serializable> implements Co
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying operation template.
|
||||
*
|
||||
* @return the underlying template.
|
||||
*/
|
||||
protected CouchbaseOperations getCouchbaseOperations() {
|
||||
return couchbaseOperations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information for the underlying template.
|
||||
*
|
||||
* @return the underlying entity information.
|
||||
*/
|
||||
protected CouchbaseEntityInformation<T, String> getEntityInformation() {
|
||||
return entityInformation;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user