Extending basic support for mapping and adding an abstract configuration.

This commit is contained in:
Michael Nitschinger
2012-12-31 09:21:51 +01:00
parent f242499554
commit 92c56ac8f9
10 changed files with 296 additions and 9 deletions

View File

@@ -27,8 +27,8 @@ import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
/**
* The CouchbaseCache class implements the common cache operations on top of
* a CouchbaseClient instance.
* The CouchbaseCache class implements the Spring Cache interface
* on top of Couchbase Server and the Couchbase Java SDK.
*/
public class CouchbaseCache implements Cache {

View File

@@ -31,8 +31,11 @@ import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractCacheManager;
/**
* The CouchbaseCacheManager handles CouchbaseClient connections and
* orchestrates them as needed.
* The CouchbaseCacheManager orchestrates 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.
*/
public class CouchbaseCacheManager extends AbstractCacheManager {

View File

@@ -0,0 +1,121 @@
/**
* Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/
package com.couchbase.spring.config;
import com.couchbase.client.CouchbaseClient;
import com.couchbase.spring.core.CouchbaseMappingContext;
import com.couchbase.spring.core.CouchbaseTemplate;
import com.couchbase.spring.core.convert.MappingCouchbaseConverter;
import com.couchbase.spring.core.mapping.Document;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.annotation.Persistent;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Base class for Spring Data Couchbase configuration using JavaConfig.
*/
@Configuration
public abstract class AbstractCouchbaseConfiguration {
/**
* Return the {@link CouchbaseClient} instance to connect to.
*/
@Bean
public abstract CouchbaseClient couchbaseClient() throws Exception;
/**
* Creates a {@link CouchbaseTemplate}.
*/
@Bean
public CouchbaseTemplate couchbaseTemplate() throws Exception {
return new CouchbaseTemplate(couchbaseClient(), mappingCouchbaseConverter());
}
/**
* Creates a {@link MappingCouchbaseConverter} using the configured {@link
* #couchbaseMappingContext}.
*/
@Bean
public MappingCouchbaseConverter mappingCouchbaseConverter() throws Exception {
return new MappingCouchbaseConverter(couchbaseMappingContext());
}
/**
* Creates a {@link CouchbaseMappingContext} equipped with entity classes
* scanned from the mapping base package.
*/
@Bean
public CouchbaseMappingContext couchbaseMappingContext() throws Exception {
CouchbaseMappingContext mappingContext = new CouchbaseMappingContext();
mappingContext.setInitialEntitySet(getInitialEntitySet());
return mappingContext;
}
/**
* Scans the mapping base package for classes annotated with {@link Document}.
*/
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
String basePackage = getMappingBasePackage();
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
if(StringUtils.hasText(basePackage)) {
ClassPathScanningCandidateComponentProvider componentProvider =
new ClassPathScanningCandidateComponentProvider(false);
componentProvider.addIncludeFilter(
new AnnotationTypeFilter(Document.class));
componentProvider.addIncludeFilter(
new AnnotationTypeFilter(Persistent.class));
for (BeanDefinition candidate :
componentProvider.findCandidateComponents(basePackage)) {
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(),
AbstractCouchbaseConfiguration.class.getClassLoader()));
}
}
return initialEntitySet;
}
/**
* 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} classes or
* {@literal null} to not enable scanning for entities.
*/
protected String getMappingBasePackage() {
return getClass().getPackage().getName();
}
}

View File

@@ -0,0 +1,64 @@
/**
* Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/
package com.couchbase.spring.core;
import com.couchbase.spring.core.mapping.BasicCouchbasePersistentEntity;
import com.couchbase.spring.core.mapping.BasicCouchbasePersistentProperty;
import com.couchbase.spring.core.mapping.CouchbasePersistentProperty;
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.mapping.context.AbstractMappingContext;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
public class CouchbaseMappingContext
extends AbstractMappingContext<BasicCouchbasePersistentEntity<?>, CouchbasePersistentProperty>
implements ApplicationContextAware {
private ApplicationContext context;
@Override
protected <T> BasicCouchbasePersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
BasicCouchbasePersistentEntity<T> entity = new BasicCouchbasePersistentEntity<T>(typeInformation);
if(context != null) {
entity.setApplicationContext(context);
}
return entity;
}
@Override
protected CouchbasePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, BasicCouchbasePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
return new BasicCouchbasePersistentProperty(field, descriptor, owner, simpleTypeHolder);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
super.setApplicationContext(applicationContext);
}
}

View File

@@ -0,0 +1,27 @@
/**
* Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/
package com.couchbase.spring.core;
public interface CouchbaseOperations {
}

View File

@@ -0,0 +1,51 @@
/**
* Copyright (C) 2009-2012 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/
package com.couchbase.spring.core;
import com.couchbase.client.CouchbaseClient;
import com.couchbase.spring.core.convert.CouchbaseConverter;
import com.couchbase.spring.core.convert.MappingCouchbaseConverter;
public class CouchbaseTemplate implements CouchbaseOperations {
private CouchbaseClient client;
private CouchbaseConverter couchbaseConverter;
public CouchbaseTemplate(CouchbaseClient client) {
this(client, null);
}
public CouchbaseTemplate(CouchbaseClient client, CouchbaseConverter converter) {
this.client = client;
this.couchbaseConverter = converter == null ? getDefaultConverter(client) : converter;
}
private CouchbaseConverter getDefaultConverter(CouchbaseClient client) {
MappingCouchbaseConverter converter = new MappingCouchbaseConverter(
new CouchbaseMappingContext());
converter.afterPropertiesSet();
return converter;
}
}

View File

@@ -40,7 +40,8 @@ public abstract class AbstractCouchbaseConverter implements CouchbaseConverter,
return conversionService;
}
public void afterPropertiesSet() throws Exception {
@Override
public void afterPropertiesSet() {
}

View File

@@ -30,6 +30,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
implements ApplicationContextAware {
@@ -39,27 +41,39 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter
CouchbasePersistentProperty> mappingContext;
@SuppressWarnings("deprecation")
public MappingCouchbaseConverter(CouchbaseFactory couchbaseFactory,
MappingContext<? extends CouchbasePersistentEntity<?>,
public MappingCouchbaseConverter(MappingContext<? extends CouchbasePersistentEntity<?>,
CouchbasePersistentProperty> mappingContext) {
super(ConversionServiceFactory.createDefaultConversionService());
this.mappingContext = mappingContext;
}
@Override
public MappingContext<? extends CouchbasePersistentEntity<?>,
CouchbasePersistentProperty> getMappingContext() {
return mappingContext;
}
@Override
public <R> R read(Class<R> type, Object s) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void write(Object t, Object s) {
throw new UnsupportedOperationException("Not supported yet.");
@Override
public void write(Object source, Object target) {
if(source == null) {
return;
}
TypeInformation<? extends Object> type = ClassTypeInformation.from(source.getClass());
writeInternal(source, target, type);
}
protected void writeInternal(Object source, Object target, TypeInformation<?> type) {
System.out.println(type.getActualType());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;

View File

@@ -43,6 +43,7 @@ public class BasicCouchbasePersistentEntity<T>
this.context = new StandardEvaluationContext();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
context.addPropertyAccessor(new BeanFactoryAccessor());